diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ec66e9fdb7..33681f30c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,15 +30,6 @@ jobs: - name: Shell lint run: make shell-lint - monitorlib-test: - name: monitorlib tests - uses: ./.github/workflows/monitoring-test.yml - with: - name: monitorlib - script: | - cd monitoring/monitorlib - make test - mock_uss-test: name: mock_uss tests uses: ./.github/workflows/monitoring-test.yml @@ -71,7 +62,7 @@ jobs: publish-gh-pages: name: Publish GitHub Pages - needs: [hygiene-tests, monitorlib-test, mock_uss-test, uss_qualifier-test, prober-test] + needs: [hygiene-tests, mock_uss-test, uss_qualifier-test, prober-test] if: ${{ always() && contains(join(needs.*.result, ','), 'success') }} runs-on: ubuntu-latest permissions: diff --git a/Makefile b/Makefile index 327689fb3b..6368fad942 100644 --- a/Makefile +++ b/Makefile @@ -11,10 +11,11 @@ endif .PHONY: format format: json-schema + docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --exclude /interfaces . cd monitoring && make format .PHONY: lint -lint: shell-lint +lint: shell-lint python-lint cd monitoring && make lint cd schemas && make lint @@ -23,7 +24,7 @@ check-hygiene: python-lint hygiene validate-uss-qualifier-docs shell-lint .PHONY: python-lint python-lint: - cd monitoring && make python-lint + docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check --exclude /interfaces . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) .PHONY: hygiene hygiene: diff --git a/monitoring/Makefile b/monitoring/Makefile index a04912bb51..663832e369 100644 --- a/monitoring/Makefile +++ b/monitoring/Makefile @@ -1,23 +1,10 @@ .PHONY: lint lint: cd uss_qualifier && make lint - cd mock_uss && make lint - cd monitorlib && make lint - cd prober && make lint - -.PHONY: python-lint -python-lint: - cd uss_qualifier && make python-lint - cd mock_uss && make python-lint - cd monitorlib && make python-lint - cd prober && make python-lint .PHONY: format format: cd uss_qualifier && make format - cd mock_uss && make format - cd monitorlib && make format - cd prober && make format image: ../requirements.txt $(shell find . -type f ! -path "*/output/*" ! -name image) $(shell find ../interfaces -type f) # Building image due to changes in the following files: $? @@ -25,7 +12,6 @@ image: ../requirements.txt $(shell find . -type f ! -path "*/output/*" ! -name i .PHONY: test test: - cd monitorlib && make test cd mock_uss && make test cd uss_qualifier && make test cd prober && make test diff --git a/monitoring/mock_uss/Makefile b/monitoring/mock_uss/Makefile index 4870651fae..ae6ad9c5b1 100644 --- a/monitoring/mock_uss/Makefile +++ b/monitoring/mock_uss/Makefile @@ -1,15 +1,3 @@ -.PHONY: lint -lint: python-lint - echo "mock_uss lint complete" - -.PHONY: python-lint -python-lint: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) - -.PHONY: format -format: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black . - .PHONY: test -test: lint +test: ./run_locally_test_geoawareness.sh diff --git a/monitoring/monitorlib/Makefile b/monitoring/monitorlib/Makefile deleted file mode 100644 index 6416aa01bf..0000000000 --- a/monitoring/monitorlib/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -.PHONY: lint -lint: python-lint - -.PHONY: python-lint -python-lint: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) - -.PHONY: format -format: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black . - -.PHONY: test -test: lint diff --git a/monitoring/monitorlib/auth.py b/monitoring/monitorlib/auth.py index edd75c66d1..d1df97f29f 100644 --- a/monitoring/monitorlib/auth.py +++ b/monitoring/monitorlib/auth.py @@ -53,25 +53,29 @@ class NoAuth(AuthAdapter): EXPIRATION = 3600 # seconds - def __init__(self, sub: str = "uss_noauth"): + def __init__(self, sub: str = "uss_noauth", aud_override: Optional[str] = None): super().__init__() self.sub = sub + self._aud_override = aud_override # Overrides method in AuthAdapter def issue_token(self, intended_audience: str, scopes: List[str]) -> str: timestamp = int((datetime.datetime.utcnow() - _UNIX_EPOCH).total_seconds()) + claims = { + "sub": self.sub, + "client_id": self.sub, + "scope": " ".join(scopes), + "aud": intended_audience, + "nbf": timestamp - 1, + "exp": timestamp + NoAuth.EXPIRATION, + "iss": "NoAuth", + "jti": str(uuid.uuid4()), + } + if self._aud_override is not None: + claims["aud"] = self._aud_override jwt = jwcrypto.jwt.JWT( header={"typ": "JWT", "alg": "RS256"}, - claims={ - "sub": self.sub, - "client_id": self.sub, - "scope": " ".join(scopes), - "aud": intended_audience, - "nbf": timestamp - 1, - "exp": timestamp + NoAuth.EXPIRATION, - "iss": "NoAuth", - "jti": str(uuid.uuid4()), - }, + claims=claims, algs=["RS256"], ) jwt.make_signed_token(NoAuth.dummy_private_key) diff --git a/monitoring/monitorlib/clients/versioning/client_interuss.py b/monitoring/monitorlib/clients/versioning/client_interuss.py index 07fe95d9f2..8fa9f7a328 100644 --- a/monitoring/monitorlib/clients/versioning/client_interuss.py +++ b/monitoring/monitorlib/clients/versioning/client_interuss.py @@ -18,7 +18,7 @@ class InterUSSVersioningClient(VersioningClient): def __init__(self, session: UTMClientSession, participant_id: ParticipantID): super(InterUSSVersioningClient, self).__init__(participant_id) self._session = session - self._server_id = participant_id + self._participant_id = participant_id def get_version(self, version_type: Optional[str]) -> GetVersionResponse: op = api.OPERATIONS[api.OperationID.GetVersion] @@ -29,8 +29,8 @@ def get_version(self, version_type: Optional[str]) -> GetVersionResponse: "query_type": QueryType.InterUSSVersioningGetVersion, "scope": Scope.ReadSystemVersions, } - if self._server_id: - kwargs["server_id"] = self._server_id + if self._participant_id: + kwargs["participant_id"] = self._participant_id query = query_and_describe(**kwargs) if query.status_code != 200: raise VersionQueryError( diff --git a/monitoring/monitorlib/fetch/__init__.py b/monitoring/monitorlib/fetch/__init__.py index dd581d90e4..1661f0eb33 100644 --- a/monitoring/monitorlib/fetch/__init__.py +++ b/monitoring/monitorlib/fetch/__init__.py @@ -235,7 +235,7 @@ class Query(ImplicitDict): request: RequestDescription response: ResponseDescription - server_id: Optional[str] + participant_id: Optional[str] """If specified, identifier of the USS/participant hosting the server involved in this query.""" query_type: Optional[QueryType] @@ -283,7 +283,7 @@ def describe_query( resp: requests.Response, initiated_at: datetime.datetime, query_type: Optional[QueryType] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> Query: query = Query( request=describe_request(resp.request, initiated_at), @@ -291,8 +291,8 @@ def describe_query( ) if query_type is not None: query.query_type = query_type - if server_id is not None: - query.server_id = server_id + if participant_id is not None: + query.participant_id = participant_id return query @@ -301,7 +301,7 @@ def query_and_describe( verb: str, url: str, query_type: Optional[QueryType] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, **kwargs, ) -> Query: """Attempt to perform a query, and then describe the results of that attempt. @@ -314,7 +314,7 @@ def query_and_describe( verb: HTTP verb to perform at the specified URL. url: URL to query. query_type: If specified, the known type of query that this is. - server_id: If specified, the participant identifier of the server being queried. + participant_id: If specified, the participant identifier of the server being queried. **kwargs: Any keyword arguments that should be applied to the .request method when invoking it. Returns: @@ -350,7 +350,7 @@ def query_and_describe( client.request(verb, url, **req_kwargs), t0, query_type=query_type, - server_id=server_id, + participant_id=participant_id, ) except (requests.Timeout, urllib3.exceptions.ReadTimeoutError) as e: failure_message = f"query_and_describe attempt {attempt + 1} from PID {os.getpid()} to {verb} {url} failed with timeout {type(e).__name__}: {str(e)}" @@ -380,7 +380,7 @@ def query_and_describe( elapsed_s=(t1 - t0).total_seconds(), reported=StringBasedDateTime(t1), ), - server_id=server_id, + participant_id=participant_id, ) if query_type is not None: result.query_type = query_type diff --git a/monitoring/monitorlib/fetch/rid.py b/monitoring/monitorlib/fetch/rid.py index 8d3867af11..e6b26c046e 100644 --- a/monitoring/monitorlib/fetch/rid.py +++ b/monitoring/monitorlib/fetch/rid.py @@ -1,15 +1,16 @@ from __future__ import annotations + import datetime from typing import Dict, List, Optional, Any, Union -from implicitdict import ImplicitDict, StringBasedDateTime import s2sphere -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, StringBasedDateTime +from uas_standards.astm.f3411 import v19, v22a from uas_standards.astm.f3411.v22a.api import RIDHeight from yaml.representer import Representer @@ -123,7 +124,7 @@ def query_flights( session: UTMClientSession, area: s2sphere.LatLngRect, include_recent_positions: bool = True, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedUSSFlights: return uss_flights( self.flights_url, @@ -131,7 +132,7 @@ def query_flights( include_recent_positions, self.rid_version, session, - server_id=server_id, + participant_id=participant_id, ) @@ -639,13 +640,30 @@ def success(self) -> bool: def errors(self) -> List[str]: raise NotImplementedError("RIDQuery.errors must be overriden") - def set_server_id(self, server_id: str): + @property + def participant_id(self) -> Optional[str]: + if self.rid_version == RIDVersion.f3411_19: + if "participant_id" in self.v19_query: + return self.v19_query.participant_id + else: + return None + elif self.rid_version == RIDVersion.f3411_22a: + if "participant_id" in self.v22a_query: + return self.v22a_query.participant_id + else: + return None + else: + raise NotImplementedError( + f"Cannot retrieve participant_id using RID version {self.rid_version}" + ) + + def set_participant_id(self, participant_id: str) -> None: if self.v19_query is not None: - self.v19_query.server_id = server_id + self.v19_query.participant_id = participant_id elif self.v22a_query is not None: - self.v22a_query.server_id = server_id + self.v22a_query.participant_id = participant_id else: - raise NotImplementedError(f"Cannot set server_id") + raise NotImplementedError(f"Cannot set participant_id") class FetchedISA(RIDQuery): @@ -721,7 +739,7 @@ def isa( rid_version: RIDVersion, session: UTMClientSession, dss_base_url: str = "", - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedISA: if rid_version == RIDVersion.f3411_19: op = v19.api.OPERATIONS[v19.api.OperationID.GetIdentificationServiceArea] @@ -732,7 +750,7 @@ def isa( op.verb, url, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ) ) elif rid_version == RIDVersion.f3411_22a: @@ -744,7 +762,7 @@ def isa( op.verb, url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ) ) else: @@ -856,7 +874,7 @@ def isas( rid_version: RIDVersion, session: UTMClientSession, dss_base_url: str = "", - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedISAs: url_time_params = "" if start_time is not None: @@ -874,7 +892,7 @@ def isas( op.verb, url, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ) ) elif rid_version == RIDVersion.f3411_22a: @@ -887,7 +905,7 @@ def isas( op.verb, url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ) ) else: @@ -964,7 +982,7 @@ def uss_flights( include_recent_positions: bool, rid_version: RIDVersion, session: UTMClientSession, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedUSSFlights: if rid_version == RIDVersion.f3411_19: query = fetch.query_and_describe( @@ -983,9 +1001,9 @@ def uss_flights( else "false", }, scope=v19.constants.Scope.Read, - server_id=server_id, + query_type=QueryType.F3411v19Flights, + participant_id=participant_id, ) - query.query_type = QueryType.F3411v19Flights return FetchedUSSFlights(v19_query=query) elif rid_version == RIDVersion.f3411_22a: params = { @@ -1004,9 +1022,9 @@ def uss_flights( flights_url, params=params, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + query_type=QueryType.F3411v22aFlights, + participant_id=participant_id, ) - query.query_type = QueryType.F3411v22aFlights return FetchedUSSFlights(v22a_query=query) else: raise NotImplementedError( @@ -1091,11 +1109,11 @@ def flight_details( enhanced_details: bool, rid_version: RIDVersion, session: UTMClientSession, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedUSSFlightDetails: url = f"{flights_url}/{flight_id}/details" if rid_version == RIDVersion.f3411_19: - kwargs = {"server_id": server_id} + kwargs = {"participant_id": participant_id} if enhanced_details: kwargs["params"] = {"enhanced": "true"} kwargs["scope"] = ( @@ -1111,7 +1129,7 @@ def flight_details( "GET", url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ) return FetchedUSSFlightDetails(v22a_query=query) else: @@ -1163,7 +1181,7 @@ def all_flights( session: UTMClientSession, dss_base_url: str = "", enhanced_details: bool = False, - server_id: Optional[str] = None, + dss_participant_id: Optional[str] = None, ) -> FetchedFlights: t = datetime.datetime.utcnow() isa_list = isas( @@ -1173,7 +1191,7 @@ def all_flights( rid_version, session, dss_base_url, - server_id=server_id, + participant_id=dss_participant_id, ) uss_flight_queries: Dict[str, FetchedUSSFlights] = {} @@ -1185,7 +1203,9 @@ def all_flights( include_recent_positions, rid_version, session, - server_id=server_id, + # Note that we have no clue at this point which participant the flights_url is for, + # this can only be determined later by comparing injected and observed flights. + participant_id=None, ) uss_flight_queries[flights_url] = flights_for_url @@ -1197,7 +1217,7 @@ def all_flights( enhanced_details, rid_version, session, - server_id=server_id, + participant_id=None, ) uss_flight_details_queries[flight.id] = details @@ -1275,7 +1295,7 @@ def subscription( rid_version: RIDVersion, session: UTMClientSession, dss_base_url: str = "", - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedSubscription: if rid_version == RIDVersion.f3411_19: op = v19.api.OPERATIONS[v19.api.OperationID.GetSubscription] @@ -1286,7 +1306,7 @@ def subscription( op.verb, url, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ) ) elif rid_version == RIDVersion.f3411_22a: @@ -1298,7 +1318,7 @@ def subscription( op.verb, url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ) ) else: @@ -1382,7 +1402,7 @@ def subscriptions( rid_version: RIDVersion, session: UTMClientSession, dss_base_url: str = "", - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> FetchedSubscriptions: if rid_version == RIDVersion.f3411_19: op = v19.api.OPERATIONS[v19.api.OperationID.SearchSubscriptions] @@ -1393,7 +1413,7 @@ def subscriptions( op.verb, url, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ) ) elif rid_version == RIDVersion.f3411_22a: @@ -1405,7 +1425,7 @@ def subscriptions( op.verb, url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ) ) else: diff --git a/monitoring/monitorlib/geo.py b/monitoring/monitorlib/geo.py index 5d6c138bcb..f06be05c73 100644 --- a/monitoring/monitorlib/geo.py +++ b/monitoring/monitorlib/geo.py @@ -7,12 +7,20 @@ import s2sphere import shapely.geometry from uas_standards.astm.f3548.v21 import api as f3548v21 +from uas_standards.astm.f3411.v19 import api as f3411v19 +from uas_standards.astm.f3411.v22a import api as f3411v22a +from uas_standards.interuss.automated_testing.rid.v1 import ( + injection as f3411testing_injection, +) EARTH_CIRCUMFERENCE_KM = 40075 EARTH_CIRCUMFERENCE_M = EARTH_CIRCUMFERENCE_KM * 1000 EARTH_RADIUS_M = 40075 * 1000 / (2 * math.pi) EARTH_AREA_M2 = 4 * math.pi * math.pow(EARTH_RADIUS_M, 2) +DISTANCE_TOLERANCE_M = 0.01 +COORD_TOLERANCE_DEG = 360 / EARTH_CIRCUMFERENCE_M * DISTANCE_TOLERANCE_M + class DistanceUnits(str, Enum): M = "M" @@ -31,9 +39,29 @@ class LatLngPoint(ImplicitDict): lng: float """Longitude (degrees)""" + @staticmethod + def from_f3411( + position: Union[ + f3411v19.RIDAircraftPosition, + f3411v22a.RIDAircraftPosition, + f3411testing_injection.RIDAircraftPosition, + ] + ): + return LatLngPoint( + lat=position.lat, + lng=position.lng, + ) + def as_s2sphere(self) -> s2sphere.LatLng: return s2sphere.LatLng.from_degrees(self.lat, self.lng) + def match(self, other: LatLngPoint) -> bool: + """Determine whether two points may be mistaken for each other.""" + return ( + abs(self.lat - other.lat) < COORD_TOLERANCE_DEG + and abs(self.lng - other.lng) < COORD_TOLERANCE_DEG + ) + class Radius(ImplicitDict): value: float diff --git a/monitoring/monitorlib/mutate/rid.py b/monitoring/monitorlib/mutate/rid.py index dd42e2cfc4..1661fd41ee 100644 --- a/monitoring/monitorlib/mutate/rid.py +++ b/monitoring/monitorlib/mutate/rid.py @@ -104,7 +104,7 @@ def upsert_subscription( rid_version: RIDVersion, utm_client: infrastructure.UTMClientSession, subscription_version: Optional[str] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> ChangedSubscription: mutation = "create" if subscription_version is None else "update" if rid_version == RIDVersion.f3411_19: @@ -137,7 +137,7 @@ def upsert_subscription( url, json=body, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ), ) elif rid_version == RIDVersion.f3411_22a: @@ -165,7 +165,7 @@ def upsert_subscription( url, json=body, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ), ) else: @@ -179,7 +179,7 @@ def delete_subscription( subscription_version: str, rid_version: RIDVersion, utm_client: infrastructure.UTMClientSession, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> ChangedSubscription: if rid_version == RIDVersion.f3411_19: op = v19.api.OPERATIONS[v19.api.OperationID.DeleteSubscription] @@ -191,7 +191,7 @@ def delete_subscription( op.verb, url, scope=v19.constants.Scope.Read, - server_id=server_id, + participant_id=participant_id, ), ) elif rid_version == RIDVersion.f3411_22a: @@ -204,7 +204,7 @@ def delete_subscription( op.verb, url, scope=v22a.constants.Scope.DisplayProvider, - server_id=server_id, + participant_id=participant_id, ), ) else: @@ -259,7 +259,7 @@ def notify( isa_id: str, utm_session: infrastructure.UTMClientSession, isa: Optional[ISA] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> ISAChangeNotification: # Note that optional `extents` are not specified if self.rid_version == RIDVersion.f3411_19: @@ -276,7 +276,7 @@ def notify( url, json=body, scope=v19.constants.Scope.Write, - server_id=server_id, + participant_id=participant_id, ) ) elif self.rid_version == RIDVersion.f3411_22a: @@ -294,7 +294,7 @@ def notify( url, json=body, scope=v22a.constants.Scope.ServiceProvider, - server_id=server_id, + participant_id=participant_id, ) ) else: @@ -450,7 +450,7 @@ def put_isa( rid_version: RIDVersion, utm_client: infrastructure.UTMClientSession, isa_version: Optional[str] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> ISAChange: mutation = "create" if isa_version is None else "update" if rid_version == RIDVersion.f3411_19: @@ -479,7 +479,7 @@ def put_isa( url, json=body, scope=v19.constants.Scope.Write, - server_id=server_id, + participant_id=participant_id, ), ) elif rid_version == RIDVersion.f3411_22a: @@ -511,7 +511,7 @@ def put_isa( url, json=body, scope=v22a.constants.Scope.ServiceProvider, - server_id=server_id, + participant_id=participant_id, ), ) else: @@ -534,7 +534,7 @@ def delete_isa( isa_version: str, rid_version: RIDVersion, utm_client: infrastructure.UTMClientSession, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> ISAChange: if rid_version == RIDVersion.f3411_19: op = v19.api.OPERATIONS[v19.api.OperationID.DeleteIdentificationServiceArea] @@ -546,7 +546,7 @@ def delete_isa( op.verb, url, scope=v19.constants.Scope.Write, - server_id=server_id, + participant_id=participant_id, ), ) elif rid_version == RIDVersion.f3411_22a: @@ -559,7 +559,7 @@ def delete_isa( op.verb, url, scope=v22a.constants.Scope.ServiceProvider, - server_id=server_id, + participant_id=participant_id, ), ) else: diff --git a/monitoring/monitorlib/mutate/scd.py b/monitoring/monitorlib/mutate/scd.py index 179e2b29e0..cc22914331 100644 --- a/monitoring/monitorlib/mutate/scd.py +++ b/monitoring/monitorlib/mutate/scd.py @@ -57,7 +57,7 @@ def put_subscription( min_alt_m: float = 0, max_alt_m: float = 3048, version: Optional[str] = None, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> MutatedSubscription: body = { "extents": Volume4D.from_values( @@ -76,7 +76,12 @@ def put_subscription( url += f"/{version}" result = MutatedSubscription( fetch.query_and_describe( - utm_client, "PUT", url, json=body, scope=scd.SCOPE_SC, server_id=server_id + utm_client, + "PUT", + url, + json=body, + scope=scd.SCOPE_SC, + participant_id=participant_id, ) ) result.mutation = "update" if version else "create" @@ -87,12 +92,12 @@ def delete_subscription( utm_client: infrastructure.UTMClientSession, subscription_id: str, version: str, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ) -> MutatedSubscription: url = f"/dss/v1/subscriptions/{subscription_id}/{version}" result = MutatedSubscription( fetch.query_and_describe( - utm_client, "DELETE", url, scope=scd.SCOPE_SC, server_id=server_id + utm_client, "DELETE", url, scope=scd.SCOPE_SC, participant_id=participant_id ) ) result.mutation = "delete" diff --git a/monitoring/prober/Makefile b/monitoring/prober/Makefile index 4470bacc64..a6bc88abb9 100644 --- a/monitoring/prober/Makefile +++ b/monitoring/prober/Makefile @@ -1,14 +1,3 @@ -.PHONY: lint -lint: python-lint - -.PHONY: python-lint -python-lint: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) - -.PHONY: format -format: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black . - .PHONY: test test: ./scripts/test_docker_fully_mocked.sh diff --git a/monitoring/uss_qualifier/Makefile b/monitoring/uss_qualifier/Makefile index 062a8dfe29..ce5d577958 100644 --- a/monitoring/uss_qualifier/Makefile +++ b/monitoring/uss_qualifier/Makefile @@ -1,18 +1,13 @@ .PHONY: lint -lint: validate-docs python-lint +lint: validate-docs .PHONY: validate-docs validate-docs: ./scripts/validate_test_definitions.sh ./scripts/format_test_suite_docs.sh --lint -.PHONY: python-lint -python-lint: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) - .PHONY: format format: format-documentation - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black . .PHONY: format-documentation format-documentation: diff --git a/monitoring/uss_qualifier/action_generators/action_generator.py b/monitoring/uss_qualifier/action_generators/action_generator.py index 7ea3093568..d72e5cfe6a 100644 --- a/monitoring/uss_qualifier/action_generators/action_generator.py +++ b/monitoring/uss_qualifier/action_generators/action_generator.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABC, abstractmethod import inspect -from typing import Generic, Dict, Optional, TypeVar, List, Type +from typing import Generic, Dict, Optional, TypeVar, List, Type, Iterator, Any from implicitdict import ImplicitDict from monitoring import uss_qualifier as uss_qualifier_module @@ -17,7 +17,6 @@ from monitoring.uss_qualifier.action_generators.documentation.definitions import ( PotentialGeneratedAction, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.definitions import ResourceID from monitoring.uss_qualifier.resources.resource import ResourceType @@ -43,8 +42,12 @@ def __init__( ) @abstractmethod - def run_next_action(self) -> Optional[TestSuiteActionReport]: - """Run the next action from the generator, or else return None if there are no more actions""" + def actions(self) -> Iterator[Any]: + """Generate the appropriate actions. + + Note that the iterator must return instances of monitoring.uss_qualifier.suites.suite.TestSuiteAction; this is + not included in type hints to avoid a circular reference. + """ raise NotImplementedError( "A concrete action generator must implement `actions` method" ) diff --git a/monitoring/uss_qualifier/action_generators/astm/f3411/for_each_dss.py b/monitoring/uss_qualifier/action_generators/astm/f3411/for_each_dss.py index 5222d47e92..5b9c348188 100644 --- a/monitoring/uss_qualifier/action_generators/astm/f3411/for_each_dss.py +++ b/monitoring/uss_qualifier/action_generators/astm/f3411/for_each_dss.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Iterator from implicitdict import ImplicitDict @@ -9,7 +9,6 @@ from monitoring.uss_qualifier.action_generators.documentation.documentation import ( list_potential_actions_for_action_declaration, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.astm.f3411 import ( DSSInstanceResource, DSSInstancesResource, @@ -23,7 +22,6 @@ from monitoring.uss_qualifier.suites.suite import ( ActionGenerator, TestSuiteAction, - ReactionToFailure, ) @@ -41,7 +39,6 @@ class ForEachDSSSpecification(ImplicitDict): class ForEachDSS(ActionGenerator[ForEachDSSSpecification]): _actions: List[TestSuiteAction] _current_action: int - _failure_reaction: ReactionToFailure @classmethod def list_potential_actions( @@ -86,15 +83,7 @@ def __init__( ) self._current_action = 0 - self._failure_reaction = specification.action_to_repeat.on_failure - def run_next_action(self) -> Optional[TestSuiteActionReport]: - if self._current_action < len(self._actions): - report = self._actions[self._current_action].run() - self._current_action += 1 - if not report.successful(): - if self._failure_reaction == ReactionToFailure.Abort: - self._current_action = len(self._actions) - return report - else: - return None + def actions(self) -> Iterator[TestSuiteAction]: + for a in self._actions: + yield a diff --git a/monitoring/uss_qualifier/action_generators/astm/f3548/for_each_dss.py b/monitoring/uss_qualifier/action_generators/astm/f3548/for_each_dss.py index 26f50e64ec..1e1d05d3cb 100644 --- a/monitoring/uss_qualifier/action_generators/astm/f3548/for_each_dss.py +++ b/monitoring/uss_qualifier/action_generators/astm/f3548/for_each_dss.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Iterator from implicitdict import ImplicitDict @@ -9,7 +9,6 @@ from monitoring.uss_qualifier.action_generators.documentation.documentation import ( list_potential_actions_for_action_declaration, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.astm.f3548.v21 import ( DSSInstancesResource, DSSInstanceResource, @@ -24,7 +23,6 @@ from monitoring.uss_qualifier.suites.suite import ( ActionGenerator, TestSuiteAction, - ReactionToFailure, ) @@ -42,7 +40,6 @@ class ForEachDSSSpecification(ImplicitDict): class ForEachDSS(ActionGenerator[ForEachDSSSpecification]): _actions: List[TestSuiteAction] _current_action: int - _failure_reaction: ReactionToFailure @classmethod def list_potential_actions( @@ -87,15 +84,7 @@ def __init__( ) self._current_action = 0 - self._failure_reaction = specification.action_to_repeat.on_failure - - def run_next_action(self) -> Optional[TestSuiteActionReport]: - if self._current_action < len(self._actions): - report = self._actions[self._current_action].run() - self._current_action += 1 - if not report.successful(): - if self._failure_reaction == ReactionToFailure.Abort: - self._current_action = len(self._actions) - return report - else: - return None + + def actions(self) -> Iterator[TestSuiteAction]: + for a in self._actions: + yield a diff --git a/monitoring/uss_qualifier/action_generators/flight_planning/planner_combinations.py b/monitoring/uss_qualifier/action_generators/flight_planning/planner_combinations.py index 6c324c3cdd..58710eaa0f 100644 --- a/monitoring/uss_qualifier/action_generators/flight_planning/planner_combinations.py +++ b/monitoring/uss_qualifier/action_generators/flight_planning/planner_combinations.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Iterator, Optional from implicitdict import ImplicitDict @@ -9,7 +9,6 @@ from monitoring.uss_qualifier.action_generators.documentation.documentation import ( list_potential_actions_for_action_declaration, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.definitions import ResourceID from monitoring.uss_qualifier.resources.flight_planning import FlightPlannersResource from monitoring.uss_qualifier.resources.flight_planning.flight_planners import ( @@ -27,7 +26,6 @@ from monitoring.uss_qualifier.suites.suite import ( ActionGenerator, TestSuiteAction, - ReactionToFailure, ) @@ -50,7 +48,6 @@ class FlightPlannerCombinations( ): _actions: List[TestSuiteAction] _current_action: int - _failure_reaction: ReactionToFailure @classmethod def list_potential_actions( @@ -128,15 +125,7 @@ def __init__( break self._current_action = 0 - self._failure_reaction = specification.action_to_repeat.on_failure - - def run_next_action(self) -> Optional[TestSuiteActionReport]: - if self._current_action < len(self._actions): - report = self._actions[self._current_action].run() - self._current_action += 1 - if not report.successful(): - if self._failure_reaction == ReactionToFailure.Abort: - self._current_action = len(self._actions) - return report - else: - return None + + def actions(self) -> Iterator[TestSuiteAction]: + for a in self._actions: + yield a diff --git a/monitoring/uss_qualifier/action_generators/interuss/mock_uss/with_locality.py b/monitoring/uss_qualifier/action_generators/interuss/mock_uss/with_locality.py index 6705e949ec..b7bfb18e2d 100644 --- a/monitoring/uss_qualifier/action_generators/interuss/mock_uss/with_locality.py +++ b/monitoring/uss_qualifier/action_generators/interuss/mock_uss/with_locality.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Iterator from implicitdict import ImplicitDict from monitoring.monitorlib.inspection import fullname @@ -9,7 +9,6 @@ from monitoring.uss_qualifier.action_generators.documentation.documentation import ( list_potential_actions_for_action_declaration, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.definitions import ResourceID from monitoring.uss_qualifier.resources.interuss.mock_uss.client import MockUSSsResource from monitoring.uss_qualifier.resources.interuss.mock_uss.locality import ( @@ -50,7 +49,6 @@ class WithLocality(ActionGenerator[WithLocalitySpecification]): _actions: List[TestSuiteAction] _current_action: int - _failure_reaction: ReactionToFailure @classmethod def list_potential_actions( @@ -137,16 +135,6 @@ def __init__( ] self._current_action = 0 - def run_next_action(self) -> Optional[TestSuiteActionReport]: - from loguru import logger - - logger.debug(f"run_next_action with current action {self._current_action}") - if self._current_action < len(self._actions): - report = self._actions[self._current_action].run() - if not report.successful() and self._current_action == 0: - self._current_action = len(self._actions) - else: - self._current_action += 1 - return report - else: - return None + def actions(self) -> Iterator[TestSuiteAction]: + for a in self._actions: + yield a diff --git a/monitoring/uss_qualifier/action_generators/repetition/repeat.py b/monitoring/uss_qualifier/action_generators/repetition/repeat.py index a2f3256af2..3d3ea9db71 100644 --- a/monitoring/uss_qualifier/action_generators/repetition/repeat.py +++ b/monitoring/uss_qualifier/action_generators/repetition/repeat.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List, Iterator from implicitdict import ImplicitDict from monitoring.uss_qualifier.action_generators.documentation.definitions import ( @@ -7,7 +7,6 @@ from monitoring.uss_qualifier.action_generators.documentation.documentation import ( list_potential_actions_for_action_declaration, ) -from monitoring.uss_qualifier.reports.report import TestSuiteActionReport from monitoring.uss_qualifier.resources.definitions import ResourceID from monitoring.uss_qualifier.resources.resource import ResourceType @@ -15,7 +14,6 @@ from monitoring.uss_qualifier.suites.suite import ( ActionGenerator, TestSuiteAction, - ReactionToFailure, ) @@ -30,7 +28,6 @@ class RepeatSpecification(ImplicitDict): class Repeat(ActionGenerator[RepeatSpecification]): _actions: List[TestSuiteAction] _current_action: int - _failure_reaction: ReactionToFailure @classmethod def list_potential_actions( @@ -50,15 +47,7 @@ def __init__( for _ in range(specification.times_to_repeat) ] self._current_action = 0 - self._failure_reaction = specification.action_to_repeat.on_failure - def run_next_action(self) -> Optional[TestSuiteActionReport]: - if self._current_action < len(self._actions): - report = self._actions[self._current_action].run() - self._current_action += 1 - if not report.successful(): - if self._failure_reaction == ReactionToFailure.Abort: - self._current_action = len(self._actions) - return report - else: - return None + def actions(self) -> Iterator[TestSuiteAction]: + for a in self._actions: + yield a diff --git a/monitoring/uss_qualifier/configurations/README.md b/monitoring/uss_qualifier/configurations/README.md index 4cf1fbb0cc..f052adf98d 100644 --- a/monitoring/uss_qualifier/configurations/README.md +++ b/monitoring/uss_qualifier/configurations/README.md @@ -8,7 +8,7 @@ To execute a test run with uss_qualifier, a uss_qualifier configuration must be When referring to a configuration, three methods may be used; see [`FileReference` documentation](../fileio.py) for more details. -* **Package-based**: refer to a dictionary (*.json, *.yaml) file located in a subfolder of the `uss_qualifier` folder using the Python module style, omitting the extension of the file name. For instance, `configurations.dev.f3548` would refer to [uss_qualifier/configurations/dev/f3548.yaml](dev/f3548.yaml). +* **Package-based**: refer to a dictionary (*.json, *.yaml) file located in a subfolder of the `uss_qualifier` folder using the Python module style, omitting the extension of the file name. For instance, `configurations.dev.uspace` would refer to [uss_qualifier/configurations/dev/uspace.yaml](dev/uspace.yaml). * **Local file**: when a configuration reference is prefixed with `file://`, it refers to a local file using the path syntax of the host operating system. * **Web file**: when a configuration reference is prefixed with `http://` or `https://`, it refers to a file accessible at the specified URL. diff --git a/monitoring/uss_qualifier/configurations/dev/dss_probing.yaml b/monitoring/uss_qualifier/configurations/dev/dss_probing.yaml index 4bb83b7e9c..6b458f94b0 100644 --- a/monitoring/uss_qualifier/configurations/dev/dss_probing.yaml +++ b/monitoring/uss_qualifier/configurations/dev/dss_probing.yaml @@ -1,81 +1,21 @@ $content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json v1: test_run: + resources: + resource_declarations: + id_generator: {$ref: 'library/resources.yaml#/id_generator'} + kentland_service_area: {$ref: 'library/resources.yaml#/kentland_service_area'} + kentland_problematically_big_area: {$ref: 'library/resources.yaml#/kentland_problematically_big_area'} + + utm_auth: {$ref: 'library/environment.yaml#/utm_auth'} + scd_dss_instances: {$ref: 'library/environment.yaml#/scd_dss_instances'} + netrid_dss_instances_v22a: {$ref: 'library/environment.yaml#/netrid_dss_instances_v22a'} + netrid_dss_instances_v19: {$ref: 'library/environment.yaml#/netrid_dss_instances_v19'} non_baseline_inputs: - v1.test_run.resources.resource_declarations.utm_auth - - v1.test_run.resources.resource_declarations.netrid_dss_instances_v19 + - v1.test_run.resources.resource_declarations.scd_dss_instances - v1.test_run.resources.resource_declarations.netrid_dss_instances_v22a - resources: - resource_declarations: - utm_auth: - resource_type: resources.communications.AuthAdapterResource - specification: - environment_variable_containing_auth_spec: AUTH_SPEC - netrid_dss_instances_v19: - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-19 - base_url: http://dss.uss1.localutm - has_private_address: true - - participant_id: uss2 - rid_version: F3411-19 - base_url: http://dss.uss2.localutm - has_private_address: true - netrid_dss_instances_v22a: - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-22a - base_url: http://dss.uss1.localutm/rid/v2 - has_private_address: true - - participant_id: uss2 - rid_version: F3411-22a - base_url: http://dss.uss2.localutm/rid/v2 - has_private_address: true - id_generator: - resource_type: resources.interuss.IDGeneratorResource - dependencies: - auth_adapter: utm_auth - specification: - whoami_audience: localhost - whoami_scope: rid.display_provider - service_area: - resource_type: resources.netrid.ServiceAreaResource - specification: - base_url: https://uss_qualifier.test.utm/dummy_base_url - footprint: - - lat: 37.1853 - lng: -80.6140 - - lat: 37.2148 - lng: -80.6140 - - lat: 37.2148 - lng: -80.5440 - - lat: 37.1853 - lng: -80.5440 - altitude_min: 0 - altitude_max: 3048 - reference_time: '2023-01-10T00:00:00.123456+00:00' - time_start: '2023-01-10T00:00:01.123456+00:00' - time_end: '2023-01-10T01:00:01.123456+00:00' - problematically_big_area: - resource_type: resources.VerticesResource - specification: - vertices: - - lat: 38 - lng: -81 - - lat: 37 - lng: -81 - - lat: 37 - lng: -80 - - lat: 38 - lng: -80 + - v1.test_run.resources.resource_declarations.netrid_dss_instances_v19 action: test_suite: suite_type: suites.interuss.dss.all_tests @@ -83,8 +23,8 @@ v1: f3411v19_dss_instances: netrid_dss_instances_v19 f3411v22a_dss_instances: netrid_dss_instances_v22a id_generator: id_generator - service_area: service_area - problematically_big_area: problematically_big_area + service_area: kentland_service_area + problematically_big_area: kentland_problematically_big_area artifacts: report: report_path: output/report_dss_probing.json diff --git a/monitoring/uss_qualifier/configurations/dev/f3548.yaml b/monitoring/uss_qualifier/configurations/dev/f3548.yaml deleted file mode 100644 index c06ccd1eff..0000000000 --- a/monitoring/uss_qualifier/configurations/dev/f3548.yaml +++ /dev/null @@ -1,32 +0,0 @@ -$content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json -v1: - test_run: - resources: - resource_declarations: - $ref: ./library/resources.yaml#/f3548_che - action: - test_suite: - suite_type: suites.astm.utm.f3548_21 - resources: - flight_planners: flight_planners - conflicting_flights: conflicting_flights - priority_preemption_flights: priority_preemption_flights - invalid_flight_intents: invalid_flight_intents - dss: scd_dss - dss_instances: scd_dss_instances - artifacts: - tested_roles: - report_path: output/tested_roles_f3548 - report: - report_path: output/report_f3548.json - tested_requirements: - output_path: output/tested_requirements_f3548 - requirement_collections: - scd: - requirement_sets: - - astm.f3548.v21.scd#Automated verification - participant_requirements: - uss1: scd - uss2: scd - validation: - $ref: ./library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/f3548/flight_intent_validation.yaml b/monitoring/uss_qualifier/configurations/dev/f3548/flight_intent_validation.yaml index 368c203b0a..acd0084997 100644 --- a/monitoring/uss_qualifier/configurations/dev/f3548/flight_intent_validation.yaml +++ b/monitoring/uss_qualifier/configurations/dev/f3548/flight_intent_validation.yaml @@ -2,16 +2,24 @@ v1: test_run: resources: resource_declarations: - "$ref": ../library/resources.yaml#/f3548_single_scenario + che_invalid_flight_intents: {$ref: '../library/resources.yaml#/che_invalid_flight_intents'} + + utm_auth: {$ref: '../library/environment.yaml#/utm_auth'} + uss1_flight_planner: {$ref: '../library/environment.yaml#/uss1_flight_planner'} + scd_dss: {$ref: '../library/environment.yaml#/scd_dss'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.uss1_flight_planner + - v1.test_run.resources.resource_declarations.scd_dss action: test_scenario: scenario_type: scenarios.astm.utm.FlightIntentValidation resources: - tested_uss: uss1 - flight_intents: invalid_flight_intents - dss: dss + tested_uss: uss1_flight_planner + flight_intents: che_invalid_flight_intents + dss: scd_dss artifacts: report: report_path: output/report_f3548_flight_intent_validation.json validation: - $ref: ./library/validation.yaml#/normal_test + $ref: ../library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_equal_priority_not_permitted.yaml b/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_equal_priority_not_permitted.yaml index 5d38bcb43e..29dbc20501 100644 --- a/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_equal_priority_not_permitted.yaml +++ b/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_equal_priority_not_permitted.yaml @@ -2,17 +2,27 @@ v1: test_run: resources: resource_declarations: - "$ref": ../library/resources.yaml#/f3548_single_scenario + che_conflicting_flights: {$ref: '../library/resources.yaml#/che_conflicting_flights'} + + utm_auth: {$ref: '../library/environment.yaml#/utm_auth'} + uss1_flight_planner: {$ref: '../library/environment.yaml#/uss1_flight_planner'} + uss2_flight_planner: {$ref: '../library/environment.yaml#/uss2_flight_planner'} + scd_dss: {$ref: '../library/environment.yaml#/scd_dss'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.uss1_flight_planner + - v1.test_run.resources.resource_declarations.uss1_flight_planner + - v1.test_run.resources.resource_declarations.scd_dss action: test_scenario: scenario_type: scenarios.astm.utm.ConflictEqualPriorityNotPermitted resources: - tested_uss: uss1 - control_uss: uss2 - flight_intents: priority_preemption_flights - dss: dss + tested_uss: uss1_flight_planner + control_uss: uss2_flight_planner + flight_intents: che_conflicting_flights + dss: scd_dss artifacts: report: report_path: output/report_f3548_nominal_planning_conflict_equal_priority_not_permitted.json validation: - $ref: ./library/validation.yaml#/normal_test + $ref: ../library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_higher_priority.yaml b/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_higher_priority.yaml index 846496d195..545ff29535 100644 --- a/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_higher_priority.yaml +++ b/monitoring/uss_qualifier/configurations/dev/f3548/nominal_planning_conflict_higher_priority.yaml @@ -2,17 +2,27 @@ v1: test_run: resources: resource_declarations: - "$ref": ../library/resources.yaml#/f3548_single_scenario + che_conflicting_flights: {$ref: '../library/resources.yaml#/che_conflicting_flights'} + + utm_auth: {$ref: '../library/environment.yaml#/utm_auth'} + uss1_flight_planner: {$ref: '../library/environment.yaml#/uss1_flight_planner'} + uss2_flight_planner: {$ref: '../library/environment.yaml#/uss2_flight_planner'} + scd_dss: {$ref: '../library/environment.yaml#/scd_dss'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.uss1_flight_planner + - v1.test_run.resources.resource_declarations.uss1_flight_planner + - v1.test_run.resources.resource_declarations.scd_dss action: test_scenario: scenario_type: scenarios.astm.utm.ConflictHigherPriority resources: - tested_uss: uss1 - control_uss: uss2 - flight_intents: priority_preemption_flights - dss: dss + tested_uss: uss1_flight_planner + control_uss: uss2_flight_planner + flight_intents: che_conflicting_flights + dss: scd_dss artifacts: report: report_path: output/report_f3548_nominal_planning_conflict_higher_priority.json validation: - $ref: ./library/validation.yaml#/normal_test + $ref: ../library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml b/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml index 7776f466b3..413fbf3cfc 100644 --- a/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml +++ b/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml @@ -40,12 +40,12 @@ v1: auth_adapter: utm_auth specification: flight_planners: - # uss1 is the mock_uss directly exposing scdsc functionality - - participant_id: uss1 - injection_base_url: http://scdsc.uss1.localutm/scdsc - # uss2 is another mock_uss directly exposing scdsc functionality - - participant_id: uss2 - injection_base_url: http://scdsc.uss2.localutm/scdsc + # uss1 is the mock_uss directly exposing scdsc functionality + - participant_id: uss1 + injection_base_url: http://scdsc.uss1.localutm/scdsc + # uss2 is another mock_uss directly exposing scdsc functionality + - participant_id: uss2 + injection_base_url: http://scdsc.uss2.localutm/scdsc # Details of conflicting flights (used in nominal planning scenario) conflicting_flights: @@ -53,7 +53,7 @@ v1: specification: planning_time: '0:05:00' file: - path: file://./test_data/che/flight_intents/conflicting_flights.json + path: file://./test_data/che/flight_intents/conflicting_flights.json # Details of priority-preemption flights (used in nominal planning priority scenario) priority_preemption_flights: @@ -61,7 +61,7 @@ v1: specification: planning_time: '0:05:00' file: - path: test_data.che.flight_intents.priority_preemption + path: test_data.che.flight_intents.conflicting_flights # Details of flights with invalid operational intents (used in flight intent validation scenario) invalid_flight_intents: @@ -69,7 +69,7 @@ v1: specification: planning_time: '0:05:00' file: - path: test_data.che.flight_intents.invalid_flight_intents + path: test_data.che.flight_intents.invalid_flight_intents # Location of DSS instance that can be used to verify flight planning outcomes dss: @@ -93,14 +93,23 @@ v1: # relative to where uss_qualifier is executed from, and are located inside the # Docker container executing uss_qualifier. artifacts: + # Write out full report content report: # Path to main report output report_path: output/report_f3548_self_contained.json - # Information about a report including a list of roles tested and which participants are attempting to fill them - tested_roles: - report_path: output/tested_roles_f3548_self_contained + # Write out a human-readable report of the requirements tested + tested_requirements: + output_path: output/tested_requirements_f3548_self_contained + requirement_collections: + scd: + requirement_collections: + - requirement_sets: + - astm.f3548.v21.scd + participant_requirements: + uss1: scd + uss2: scd - graph: - # Path to output GraphViz test file summarizing test run - gv_path: output/report_f3548_self_contained.gv + # Write out a human-readable report showing the sequence of events of the test + sequence_view: + output_path: output/sequence_f3548_self_contained diff --git a/monitoring/uss_qualifier/configurations/dev/faa/uft/local_message_signing.yaml b/monitoring/uss_qualifier/configurations/dev/faa/uft/local_message_signing.yaml deleted file mode 100644 index 7eaf59a31d..0000000000 --- a/monitoring/uss_qualifier/configurations/dev/faa/uft/local_message_signing.yaml +++ /dev/null @@ -1,65 +0,0 @@ -v1: - test_run: - resources: - resource_declarations: - "$ref": ../../library/resources.yaml#/common - flight_planners: - resource_type: resources.flight_planning.FlightPlannersResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planners: - - participant_id: uss1 - injection_base_url: http://host.docker.internal:8074/scdsc - - participant_id: uss2 - injection_base_url: http://host.docker.internal:8074/scdsc - - participant_id: mock_uss - injection_base_url: http://host.docker.internal:8074/scdsc - combination_selector: - resource_type: resources.flight_planning.FlightPlannerCombinationSelectorResource - specification: - must_include: - - mock_uss - maximum_roles: - mock_uss: 1 - conflicting_flights: - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: file://./test_data/che/flight_intents/conflicting_flights.json - priority_preemption_flights: - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: test_data.che.flight_intents.priority_preemption - dss: - resource_type: resources.astm.f3548.v21.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - base_url: http://host.docker.internal:8082 - mock_uss: - resource_type: resources.interuss.mock_uss.client.MockUSSResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: mock_uss - mock_uss_base_url: http://host.docker.internal:8074 - - action: - test_suite: - suite_type: suites.faa.uft.message_signing - resources: - mock_uss: mock_uss - flight_planners: flight_planners - combination_selector: combination_selector - conflicting_flights: conflicting_flights - priority_preemption_flights: priority_preemption_flights - dss: dss - - artifacts: - report: - report_path: output/report.json diff --git a/monitoring/uss_qualifier/configurations/dev/general_flight_auth.yaml b/monitoring/uss_qualifier/configurations/dev/general_flight_auth.yaml index ee0dd0e734..f9126e75d4 100644 --- a/monitoring/uss_qualifier/configurations/dev/general_flight_auth.yaml +++ b/monitoring/uss_qualifier/configurations/dev/general_flight_auth.yaml @@ -3,13 +3,12 @@ v1: test_run: resources: resource_declarations: - $ref: ./library/resources.yaml#/general_flight_authorization + example_flight_check_table: {$ref: 'library/resources.yaml#/example_flight_check_table'} action: test_scenario: scenario_type: scenarios.interuss.flight_authorization.GeneralFlightAuthorization resources: - table: flight_check_table - on_failure: Abort + table: example_flight_check_table artifacts: report: report_path: output/report_general_flight_auth.json diff --git a/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.json b/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.json deleted file mode 100644 index e06d3b0d09..0000000000 --- a/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "$content_schema": "monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json", - "v1": { - "test_run": { - "resources": { - "resource_declarations": { - "$ref": "./library/resources.yaml#/net_rid_sims" - } - }, - "action": { - "test_suite": { - "suite_definition": { - "name": "Generate RID test data twice", - "resources": { - "adjacent_circular_flights_data": "resources.netrid.FlightDataResource", - "adjacent_circular_storage_config": "resources.netrid.FlightDataStorageResource", - "kml_flights_data": "resources.netrid.FlightDataResource", - "kml_storage_config": "resources.netrid.FlightDataStorageResource" - }, - "actions": [ - { - "action_generator": { - "generator_type": "action_generators.repetition.Repeat", - "specification": { - "action_to_repeat": { - "test_suite": { - "suite_definition": { - "name": "Generate RID test data", - "resources": { - "adjacent_circular_flights_data": "resources.netrid.FlightDataResource", - "adjacent_circular_storage_config": "resources.netrid.FlightDataStorageResource", - "kml_flights_data": "resources.netrid.FlightDataResource", - "kml_storage_config": "resources.netrid.FlightDataStorageResource" - }, - "actions": [ - { - "test_scenario": { - "scenario_type": "scenarios.astm.netrid.StoreFlightData", - "resources": { - "flights_data": "adjacent_circular_flights_data", - "storage_configuration": "adjacent_circular_storage_config" - } - }, - "on_failure": "Continue" - }, - { - "test_scenario": { - "scenario_type": "scenarios.astm.netrid.StoreFlightData", - "resources": { - "flights_data": "kml_flights_data", - "storage_configuration": "kml_storage_config" - } - }, - "on_failure": "Continue" - } - ] - }, - "resources": { - "adjacent_circular_flights_data": "adjacent_circular_flights_data", - "adjacent_circular_storage_config": "adjacent_circular_storage_config", - "kml_flights_data": "kml_flights_data", - "kml_storage_config": "kml_storage_config" - } - }, - "on_failure": "Abort" - }, - "times_to_repeat": 2 - }, - "resources": { - "adjacent_circular_flights_data": "adjacent_circular_flights_data", - "adjacent_circular_storage_config": "adjacent_circular_storage_config", - "kml_flights_data": "kml_flights_data", - "kml_storage_config": "kml_storage_config" - } - }, - "on_failure": "Continue" - } - ] - }, - "resources": { - "adjacent_circular_flights_data": "adjacent_circular_flights_data", - "adjacent_circular_storage_config": "adjacent_circular_storage_config", - "kml_flights_data": "kml_flights_data", - "kml_storage_config": "kml_storage_config" - } - } - } - }, - "validation": { - "$ref": "./library/validation.yaml#/normal_test" - } - } -} diff --git a/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.yaml b/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.yaml new file mode 100644 index 0000000000..6ec98c40da --- /dev/null +++ b/monitoring/uss_qualifier/configurations/dev/generate_rid_test_data.yaml @@ -0,0 +1,65 @@ +$content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json +v1: + test_run: + resources: + resource_declarations: + che_adjacent_circular_flights_data: {$ref: 'library/resources.yaml#/che_adjacent_circular_flights_data'} + dc_flights_data: {$ref: 'library/resources.yaml#/dc_flights_data'} + + adjacent_circular_storage_config: {$ref: 'library/resources.yaml#/adjacent_circular_storage_config'} + kml_storage_config: {$ref: 'library/resources.yaml#/kml_storage_config'} + action: + test_suite: + resources: + adjacent_circular_flights_data: che_adjacent_circular_flights_data + adjacent_circular_storage_config: adjacent_circular_storage_config + kml_flights_data: dc_flights_data + kml_storage_config: kml_storage_config + suite_definition: + name: Generate RID test data twice + resources: + adjacent_circular_flights_data: resources.netrid.FlightDataResource + adjacent_circular_storage_config: resources.netrid.FlightDataStorageResource + kml_flights_data: resources.netrid.FlightDataResource + kml_storage_config: resources.netrid.FlightDataStorageResource + actions: + - action_generator: + generator_type: action_generators.repetition.Repeat + specification: + action_to_repeat: + test_suite: + suite_definition: + name: Generate RID test data + resources: + adjacent_circular_flights_data: resources.netrid.FlightDataResource + adjacent_circular_storage_config: resources.netrid.FlightDataStorageResource + kml_flights_data: resources.netrid.FlightDataResource + kml_storage_config: resources.netrid.FlightDataStorageResource + actions: + - test_scenario: + scenario_type: scenarios.astm.netrid.StoreFlightData + resources: + flights_data: adjacent_circular_flights_data + storage_configuration: adjacent_circular_storage_config + on_failure: Continue + - test_scenario: + scenario_type: scenarios.astm.netrid.StoreFlightData + resources: + flights_data: kml_flights_data + storage_configuration: kml_storage_config + on_failure: Continue + resources: + adjacent_circular_flights_data: adjacent_circular_flights_data + adjacent_circular_storage_config: adjacent_circular_storage_config + kml_flights_data: kml_flights_data + kml_storage_config: kml_storage_config + on_failure: Abort + times_to_repeat: 2 + resources: + adjacent_circular_flights_data: adjacent_circular_flights_data + adjacent_circular_storage_config: adjacent_circular_storage_config + kml_flights_data: kml_flights_data + kml_storage_config: kml_storage_config + on_failure: Continue + validation: + "$ref": "./library/validation.yaml#/normal_test" diff --git a/monitoring/uss_qualifier/configurations/dev/geospatial_comprehension.yaml b/monitoring/uss_qualifier/configurations/dev/geospatial_comprehension.yaml index 9e45824562..d96d005596 100644 --- a/monitoring/uss_qualifier/configurations/dev/geospatial_comprehension.yaml +++ b/monitoring/uss_qualifier/configurations/dev/geospatial_comprehension.yaml @@ -3,13 +3,12 @@ v1: test_run: resources: resource_declarations: - $ref: ./library/resources.yaml#/geospatial_map + example_feature_check_table: {$ref: 'library/resources.yaml#/example_feature_check_table'} action: test_scenario: scenario_type: scenarios.interuss.geospatial_map.GeospatialFeatureComprehension resources: - table: feature_check_table - on_failure: Abort + table: example_feature_check_table artifacts: report: report_path: output/report_geospatial_comprehension.json diff --git a/monitoring/uss_qualifier/configurations/dev/library/README.md b/monitoring/uss_qualifier/configurations/dev/library/README.md index 929b9d0383..509245ed73 100644 --- a/monitoring/uss_qualifier/configurations/dev/library/README.md +++ b/monitoring/uss_qualifier/configurations/dev/library/README.md @@ -1,5 +1,5 @@ -# dev library +# dev configuration library This folder contains configuration components intended to be included in other components or configurations. -The field `$content_schema` is used to annotate intended content type, and matching JSON Schema may be found in the [`schemas` folder of this repo](../../../../../schemas). +The field `$content_schema` is used to annotate intended content type, and matching JSON Schema may be found in the [`schemas` folder of this repo](../../../../../schemas). Its value is not used programmatically. diff --git a/monitoring/uss_qualifier/configurations/dev/library/environment.yaml b/monitoring/uss_qualifier/configurations/dev/library/environment.yaml index 89eace0848..eb42d6ad5d 100644 --- a/monitoring/uss_qualifier/configurations/dev/library/environment.yaml +++ b/monitoring/uss_qualifier/configurations/dev/library/environment.yaml @@ -1,211 +1 @@ -# The resources in this file describe the system/environment under test and should not change the test being run. - -non_baseline_inputs: - non_baseline_inputs: - - v1.test_run.resources.resource_declarations.utm_auth - - v1.test_run.resources.resource_declarations.netrid_service_providers_v19 - - v1.test_run.resources.resource_declarations.netrid_service_providers_v22a - - v1.test_run.resources.resource_declarations.netrid_observers_v19 - - v1.test_run.resources.resource_declarations.netrid_observers_v22a - - v1.test_run.resources.resource_declarations.netrid_dss_instances_v19 - - v1.test_run.resources.resource_declarations.netrid_dss_instances_v22a - - v1.test_run.resources.resource_declarations.netrid_dss_instance_v19 - - v1.test_run.resources.resource_declarations.netrid_dss_instance_v22a - - v1.test_run.resources.resource_declarations.flight_planners - - v1.test_run.resources.resource_declarations.dss - - v1.test_run.resources.resource_declarations.uss1 - - v1.test_run.resources.resource_declarations.uss2 - - -common: - utm_auth: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.communications.AuthAdapterResource - specification: - environment_variable_containing_auth_spec: AUTH_SPEC - -net_rid: - netrid_service_providers_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDServiceProviders - dependencies: - auth_adapter: utm_auth - specification: - service_providers: - - participant_id: uss2 - injection_base_url: http://v19.ridsp.uss2.localutm/ridsp/injection - local_debug: true - netrid_service_providers_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDServiceProviders - dependencies: - auth_adapter: utm_auth - specification: - service_providers: - - participant_id: uss1 - injection_base_url: http://v22a.ridsp.uss1.localutm/ridsp/injection - local_debug: true - netrid_observers_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDObserversResource - dependencies: - auth_adapter: utm_auth - specification: - observers: - - participant_id: uss3 - observation_base_url: http://v19.riddp.uss3.localutm/riddp/observation - local_debug: true - netrid_observers_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDObserversResource - dependencies: - auth_adapter: utm_auth - specification: - observers: - - participant_id: uss1 - observation_base_url: http://v22a.riddp.uss1.localutm/riddp/observation - local_debug: true - netrid_dss_instances_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-19 - base_url: http://dss.uss1.localutm - has_private_address: true - - participant_id: uss2 - rid_version: F3411-19 - base_url: http://dss.uss2.localutm - has_private_address: true - netrid_dss_instances_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-22a - base_url: http://dss.uss1.localutm/rid/v2 - has_private_address: true - - participant_id: uss2 - rid_version: F3411-22a - base_url: http://dss.uss2.localutm/rid/v2 - has_private_address: true - netrid_dss_instance_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - rid_version: F3411-19 - base_url: http://dss.uss1.localutm - has_private_address: true - netrid_dss_instance_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - rid_version: F3411-22a - base_url: http://dss.uss1.localutm/rid/v2 - has_private_address: true - -f3548: - flight_planners: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannersResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planners: - # uss1 is the mock_uss directly exposing scdsc functionality - - participant_id: uss1 - injection_base_url: http://scdsc.uss1.localutm/scdsc - local_debug: true - - # The atproxy has been disabled since it is suspected to be responsible of issue #28. Replaced by another simple mock_uss - # # uss2 uses atproxy, with requests being fulfilled by mock_uss with atproxy_client functionality enabled - # - participant_id: uss2 - # injection_base_url: http://host.docker.internal:8075/scd - - # uss2 is the mock_uss directly exposing scdsc functionality - - participant_id: uss2 - injection_base_url: http://scdsc.uss2.localutm/scdsc - local_debug: true - scd_dss: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3548.v21.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - base_url: http://dss.uss1.localutm - has_private_address: true - scd_dss_instances: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3548.v21.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - base_url: http://dss.uss1.localutm - has_private_address: true - - participant_id: uss2 - base_url: http://dss.uss2.localutm - has_private_address: true - -f3548_single_scenario: - uss1: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannerResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planner: - participant_id: uss1 - injection_base_url: http://scdsc.uss1.localutm/scdsc - local_debug: true - uss2: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannerResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planner: - participant_id: uss2 - injection_base_url: http://scdsc.uss2.localutm/scdsc - local_debug: true - -mock_uss_instances: - mock_uss_instances_scdsc: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.mock_uss.client.MockUSSsResource - dependencies: - auth_adapter: utm_auth - specification: - instances: - - mock_uss_base_url: http://scdsc.uss1.localutm - participant_id: uss1 - - mock_uss_base_url: http://scdsc.uss2.localutm - participant_id: uss2 - -scd_version_providers: - version_providers: - resource_type: resources.versioning.VersionProvidersResource - dependencies: - auth_adapter: utm_auth - specification: - instances: - - participant_id: uss1 - interuss: - base_url: http://scdsc.uss1.localutm/versioning - - participant_id: uss2 - interuss: - base_url: http://scdsc.uss2.localutm/versioning +$ref: environment_containers.yaml diff --git a/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml b/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml new file mode 100644 index 0000000000..7e593e6127 --- /dev/null +++ b/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml @@ -0,0 +1,217 @@ +# The resources in this file describe the system/environment under test and should not change the test being run. +# This file assumes the use of a container-based local environment. + +# ===== Auth ===== + +utm_auth: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.communications.AuthAdapterResource + specification: + environment_variable_containing_auth_spec: AUTH_SPEC + +# ===== NetRID ===== + +netrid_service_providers_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDServiceProviders + dependencies: + auth_adapter: utm_auth + specification: + service_providers: + - participant_id: uss2 + injection_base_url: http://v19.ridsp.uss2.localutm/ridsp/injection + local_debug: true + +netrid_service_providers_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDServiceProviders + dependencies: + auth_adapter: utm_auth + specification: + service_providers: + - participant_id: uss1 + injection_base_url: http://v22a.ridsp.uss1.localutm/ridsp/injection + local_debug: true + +netrid_observers_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDObserversResource + dependencies: + auth_adapter: utm_auth + specification: + observers: + - participant_id: uss3 + observation_base_url: http://v19.riddp.uss3.localutm/riddp/observation + local_debug: true + +netrid_observers_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDObserversResource + dependencies: + auth_adapter: utm_auth + specification: + observers: + - participant_id: uss1 + observation_base_url: http://v22a.riddp.uss1.localutm/riddp/observation + local_debug: true + +netrid_dss_instances_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + rid_version: F3411-19 + base_url: http://dss.uss1.localutm + has_private_address: true + - participant_id: uss2 + rid_version: F3411-19 + base_url: http://dss.uss2.localutm + has_private_address: true + +netrid_dss_instances_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + rid_version: F3411-22a + base_url: http://dss.uss1.localutm/rid/v2 + has_private_address: true + - participant_id: uss2 + rid_version: F3411-22a + base_url: http://dss.uss2.localutm/rid/v2 + has_private_address: true + +netrid_dss_instance_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + rid_version: F3411-19 + base_url: http://dss.uss1.localutm + has_private_address: true + +netrid_dss_instance_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + rid_version: F3411-22a + base_url: http://dss.uss1.localutm/rid/v2 + has_private_address: true + +# ===== Flight planning ===== + +all_flight_planners: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannersResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planners: + - participant_id: uss1 + injection_base_url: http://scdsc.uss1.localutm/scdsc + local_debug: true + + # The atproxy has been disabled since it is suspected to be responsible of issue #28. Replaced by another simple mock_uss + # # uss2 uses atproxy, with requests being fulfilled by mock_uss with atproxy_client functionality enabled + # - participant_id: uss2 + # injection_base_url: http://host.docker.internal:8075/scd + + - participant_id: uss2 + injection_base_url: http://scdsc.uss2.localutm/scdsc + local_debug: true + +uss1_flight_planner: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannerResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planner: + participant_id: uss1 + injection_base_url: http://scdsc.uss1.localutm/scdsc + local_debug: true + +uss2_flight_planner: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannerResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planner: + participant_id: uss2 + injection_base_url: http://scdsc.uss2.localutm/scdsc + local_debug: true + +# ===== F3548 ===== + +scd_dss: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3548.v21.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + base_url: http://dss.uss1.localutm + has_private_address: true + +scd_dss_instances: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3548.v21.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + base_url: http://dss.uss1.localutm + has_private_address: true + - participant_id: uss2 + base_url: http://dss.uss2.localutm + has_private_address: true + +# ===== mock_uss instances ===== + +mock_uss_instance_uss1: + resource_type: resources.interuss.mock_uss.client.MockUSSResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: mock_uss + mock_uss_base_url: http://scdsc.uss1.localutm + +mock_uss_instances_scdsc: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.mock_uss.client.MockUSSsResource + dependencies: + auth_adapter: utm_auth + specification: + instances: + - mock_uss_base_url: http://scdsc.uss1.localutm + participant_id: uss1 + - mock_uss_base_url: http://scdsc.uss2.localutm + participant_id: uss2 + +# ===== System versioning ===== + +scd_version_providers: + resource_type: resources.versioning.VersionProvidersResource + dependencies: + auth_adapter: utm_auth + specification: + instances: + - participant_id: uss1 + interuss: + base_url: http://scdsc.uss1.localutm/versioning + - participant_id: uss2 + interuss: + base_url: http://scdsc.uss2.localutm/versioning diff --git a/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml b/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml new file mode 100644 index 0000000000..e25be6824d --- /dev/null +++ b/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml @@ -0,0 +1,217 @@ +# The resources in this file describe the system/environment under test and should not change the test being run. +# This file assumes the use of a host-machine local environment. + +# ===== Auth ===== + +utm_auth: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.communications.AuthAdapterResource + specification: + environment_variable_containing_auth_spec: AUTH_SPEC + +# ===== NetRID ===== + +netrid_service_providers_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDServiceProviders + dependencies: + auth_adapter: utm_auth + specification: + service_providers: + - participant_id: uss2 + injection_base_url: http://localhost:8071/ridsp/injection + local_debug: true + +netrid_service_providers_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDServiceProviders + dependencies: + auth_adapter: utm_auth + specification: + service_providers: + - participant_id: uss1 + injection_base_url: http://localhost:8081/ridsp/injection + local_debug: true + +netrid_observers_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDObserversResource + dependencies: + auth_adapter: utm_auth + specification: + observers: + - participant_id: uss3 + observation_base_url: http://localhost:8073/riddp/observation + local_debug: true + +netrid_observers_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.NetRIDObserversResource + dependencies: + auth_adapter: utm_auth + specification: + observers: + - participant_id: uss1 + observation_base_url: http://localhost:8083/riddp/observation + local_debug: true + +netrid_dss_instances_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + rid_version: F3411-19 + base_url: http://localhost:8082 + has_private_address: true + - participant_id: uss2 + rid_version: F3411-19 + base_url: http://localhost:8082 + has_private_address: true + +netrid_dss_instances_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + rid_version: F3411-22a + base_url: http://localhost:8082/rid/v2 + has_private_address: true + - participant_id: uss2 + rid_version: F3411-22a + base_url: http://localhost:8082/rid/v2 + has_private_address: true + +netrid_dss_instance_v19: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + rid_version: F3411-19 + base_url: http://localhost:8082 + has_private_address: true + +netrid_dss_instance_v22a: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3411.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + rid_version: F3411-22a + base_url: http://localhost:8082/rid/v2 + has_private_address: true + +# ===== Flight planning ===== + +all_flight_planners: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannersResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planners: + - participant_id: uss1 + injection_base_url: http://localhost:8074/scdsc + local_debug: true + + # The atproxy has been disabled since it is suspected to be responsible of issue #28. Replaced by another simple mock_uss + # # uss2 uses atproxy, with requests being fulfilled by mock_uss with atproxy_client functionality enabled + # - participant_id: uss2 + # injection_base_url: http://host.docker.internal:8075/scd + + - participant_id: uss2 + injection_base_url: http://localhost:8094/scdsc + local_debug: true + +uss1_flight_planner: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannerResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planner: + participant_id: uss1 + injection_base_url: http://localhost:8074/scdsc + local_debug: true + +uss2_flight_planner: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightPlannerResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planner: + participant_id: uss2 + injection_base_url: http://localhost:8094/scdsc + local_debug: true + +# ===== F3548 ===== + +scd_dss: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3548.v21.DSSInstanceResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: uss1 + base_url: http://localhost:8082 + has_private_address: true + +scd_dss_instances: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.astm.f3548.v21.DSSInstancesResource + dependencies: + auth_adapter: utm_auth + specification: + dss_instances: + - participant_id: uss1 + base_url: http://localhost:8082 + has_private_address: true + - participant_id: uss2 + base_url: http://localhost:8082 + has_private_address: true + +# ===== mock_uss instances ===== + +mock_uss_instance_uss1: + resource_type: resources.interuss.mock_uss.client.MockUSSResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: mock_uss + mock_uss_base_url: http://localhost:8074 + +mock_uss_instances_scdsc: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.mock_uss.client.MockUSSsResource + dependencies: + auth_adapter: utm_auth + specification: + instances: + - mock_uss_base_url: http://localhost:8074 + participant_id: uss1 + - mock_uss_base_url: http://localhost:8094 + participant_id: uss2 + +# ===== System versioning ===== + +scd_version_providers: + resource_type: resources.versioning.VersionProvidersResource + dependencies: + auth_adapter: utm_auth + specification: + instances: + - participant_id: uss1 + interuss: + base_url: http://localhost:8074/versioning + - participant_id: uss2 + interuss: + base_url: http://localhost:8094/versioning diff --git a/monitoring/uss_qualifier/configurations/dev/library/resources.yaml b/monitoring/uss_qualifier/configurations/dev/library/resources.yaml index 2914bf1bf4..ff155301c1 100644 --- a/monitoring/uss_qualifier/configurations/dev/library/resources.yaml +++ b/monitoring/uss_qualifier/configurations/dev/library/resources.yaml @@ -1,393 +1,375 @@ -all: - allOf: - - $ref: '#/uspace' - - $ref: '#/net_rid_sims' - - $ref: '#/general_flight_authorization' - - $ref: '#/geospatial_map' - - $ref: '#/mock_uss_instances' - - $ref: '#/uspace_versioning' +# ===== NetRID ===== -uspace: - allOf: - - $ref: '#/net_rid' - - $ref: '#/flight_auth' - - $ref: '#/uspace_versioning' +netrid_observation_evaluation_configuration: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.EvaluationConfigurationResource + specification: { } -net_rid: - allOf: - - $ref: '#/common' - - $ref: 'environment.yaml#/net_rid' - netrid_observation_evaluation_configuration: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.EvaluationConfigurationResource - specification: { } - id_generator: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.IDGeneratorResource - dependencies: - auth_adapter: utm_auth - specification: - whoami_audience: localhost - whoami_scope: rid.display_provider - service_area: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.ServiceAreaResource - specification: - base_url: https://uss_qualifier.test.utm/dummy_base_url - footprint: - - lat: 37.1853 - lng: -80.6140 - - lat: 37.2148 - lng: -80.6140 - - lat: 37.2148 - lng: -80.5440 - - lat: 37.1853 - lng: -80.5440 - altitude_min: 0 - altitude_max: 3048 - reference_time: '2023-01-10T00:00:00.123456+00:00' - time_start: '2023-01-10T00:00:01.123456+00:00' - time_end: '2023-01-10T01:00:01.123456+00:00' - problematically_big_area: # A huge (as in "too big") area for checks around area sizes - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.VerticesResource - specification: - vertices: - - lat: -23 - lng: 130 - - lat: -24 - lng: 130 - - lat: -24 - lng: 132 - - lat: -23 - lng: 132 +id_generator: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.IDGeneratorResource + dependencies: + auth_adapter: utm_auth + specification: + whoami_audience: localhost + whoami_scope: rid.display_provider -net_rid_sims: - adjacent_circular_flights_data: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataResource - specification: - adjacent_circular_flights_simulation_source: { } - adjacent_circular_storage_config: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataStorageResource - specification: - flight_record_collection_path: "./output/test_data.che.netrid.circular_flights.json" - kml_flights_data: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataResource - specification: - kml_source: - kml_file: - path: file://./test_data/usa/netrid/dcdemo.kml - kml_storage_config: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataStorageResource - specification: - flight_record_collection_path: "./output/test_data.usa.netrid.dcdemo_flights.json" - kentland_flights_data: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataResource - specification: - kml_source: - kml_file: - path: file://./test_data/usa/kentland/rid.kml - flight_start_delay: 5s - foca_flights_data: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.FlightDataResource - specification: - kml_source: - kml_file: - path: file://./test_data/che/rid/foca.kml - flight_start_delay: 5s +kentland_service_area: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.ServiceAreaResource + specification: + base_url: https://uss_qualifier.test.utm/dummy_base_url + footprint: + - lat: 37.1853 + lng: -80.6140 + - lat: 37.2148 + lng: -80.6140 + - lat: 37.2148 + lng: -80.5440 + - lat: 37.1853 + lng: -80.5440 + altitude_min: 0 + altitude_max: 3048 + reference_time: '2023-01-10T00:00:00.123456+00:00' + time_start: '2023-01-10T00:00:01.123456+00:00' + time_end: '2023-01-10T01:00:01.123456+00:00' -flight_auth: - $ref: '#/f3548_che' - invalid_flight_auth_flights: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: file://./test_data/che/flight_intents/invalid_flight_auths.json +au_problematically_big_area: # A huge (as in "too big") area for checks around area sizes + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.VerticesResource + specification: + vertices: + - lat: -23 + lng: 130 + - lat: -24 + lng: 130 + - lat: -24 + lng: 132 + - lat: -23 + lng: 132 -che_flight_intents: - conflicting_flights: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: file://./test_data/che/flight_intents/conflicting_flights.json - priority_preemption_flights: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: test_data.che.flight_intents.priority_preemption - # Note that this hash_sha512 field can be safely deleted if the content changes - hash_sha512: 432ea57009b6a41b3af43cb9431a0627a487eac0a04511fbccd85d9fcac193b11976ad2dbc07d9efa41ceaf7a9338b39064ede6eeb5755be3966d2e17e7d555a - invalid_flight_intents: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: test_data.che.flight_intents.invalid_flight_intents +kentland_problematically_big_area: + resource_type: resources.VerticesResource + specification: + vertices: + - lat: 38 + lng: -81 + - lat: 37 + lng: -81 + - lat: 37 + lng: -80 + - lat: 38 + lng: -80 -kentland_flight_intents: - conflicting_flights: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: file://./test_data/usa/kentland/flight_intents/conflicting_flights.yaml - priority_preemption_flights: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: test_data.usa.kentland.flight_intents.priority_preemption - invalid_flight_intents: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightIntentsResource - specification: - planning_time: '0:05:00' - file: - path: test_data.usa.kentland.flight_intents.invalid_flight_intents +# ===== NetRID flights data ===== -f3548_che: - allOf: - - $ref: '#/f3548' - - $ref: '#/che_flight_intents' +che_adjacent_circular_flights_data: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataResource + specification: + adjacent_circular_flights_simulation_source: { } -f3548_kentland: - allOf: - - $ref: '#/f3548' - - $ref: '#/kentland_flight_intents' +dc_flights_data: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataResource + specification: + kml_source: + kml_file: + path: file://./test_data/usa/netrid/dcdemo.kml -f3548: - allOf: - - $ref: '#/common' - - $ref: 'environment.yaml#/f3548' +kentland_flights_data: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataResource + specification: + kml_source: + kml_file: + path: file://./test_data/usa/kentland/rid.kml + flight_start_delay: 5s -f3548_single_scenario: - allOf: - - $ref: '#/f3548_che' - - $ref: 'environment.yaml#/f3548_single_scenario' +foca_flights_data: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataResource + specification: + kml_source: + kml_file: + path: file://./test_data/che/rid/foca.kml + flight_start_delay: 5s -general_flight_authorization: - flight_check_table: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.flight_authorization.FlightCheckTableResource - specification: - table: - rows: - - flight_check_id: TEST_001 - requirement_ids: - - 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: +# ===== NetRID data generation/simulation/storage ===== + +adjacent_circular_storage_config: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataStorageResource + specification: + flight_record_collection_path: "./output/test_data.che.netrid.circular_flights.json" + +kml_storage_config: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.netrid.FlightDataStorageResource + specification: + flight_record_collection_path: "./output/test_data.usa.netrid.dcdemo_flights.json" + +# ===== Flight planning intents ===== + +che_invalid_flight_auth_flights: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: file://./test_data/che/flight_intents/invalid_flight_auths.json + +che_conflicting_flights: + # Includes flight intents for both equal-priority-not-permitted and higher-priority + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: file://./test_data/che/flight_intents/conflicting_flights.json + # Note that this hash_sha512 field can be safely deleted if the content changes + hash_sha512: 6467e88fb69702216dabe1f9723b68fe68a1a9d4b1a40e3af5c0b1ed233061a088c9c30be8a0ada447b18f2c6354db52d84aa12c1e7dfd13f99262d91ba173f4 + +che_invalid_flight_intents: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: test_data.che.flight_intents.invalid_flight_intents + +kentland_conflicting_flights: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: file://./test_data/usa/kentland/flight_intents/conflicting_flights.yaml + +kentland_priority_preemption_flights: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: test_data.usa.kentland.flight_intents.priority_preemption + +kentland_invalid_flight_intents: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.flight_planning.FlightIntentsResource + specification: + planning_time: '0:05:00' + file: + path: test_data.usa.kentland.flight_intents.invalid_flight_intents + +# ===== General flight authorization ===== + +example_flight_check_table: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.flight_authorization.FlightCheckTableResource + specification: + table: + rows: + - flight_check_id: TEST_001 + requirement_ids: + - 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 - 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_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 + 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_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 - reference: SFC - altitude_upper: - value: 5000 - units: FT - reference: W84 - start_time: - next_day: - time_zone: +02:00 - starting_from: - offset_from: - starting_from: - start_of_test: {} - offset: 12h - duration: 5m - conditions_expectation: MustBePresent + 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: + starting_from: + start_of_test: { } + offset: 12h + duration: 5m + conditions_expectation: MustBePresent -geospatial_map: - feature_check_table: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.geospatial_map.FeatureCheckTableResource - specification: - table: - rows: - - geospatial_check_id: TEST_001 - requirement_ids: - - REQ_002 - - REQ_007 - description: The first test step defined by the test designer - operation_rule_set: Rules1 - restriction_source: ThisRegulator - volumes: - - outline_circle: - center: - lng: 7.4774 - lat: 46.9749 - radius: - value: 100 - units: M - altitude_lower: - value: 0 +# ===== Geospatial feature comprehension ===== + +example_feature_check_table: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.geospatial_map.FeatureCheckTableResource + specification: + table: + rows: + - geospatial_check_id: TEST_001 + requirement_ids: + - REQ_002 + - REQ_007 + description: The first test step defined by the test designer + operation_rule_set: Rules1 + restriction_source: ThisRegulator + volumes: + - outline_circle: + center: + lng: 7.4774 + lat: 46.9749 + radius: + value: 100 units: M - reference: SFC - altitude_upper: + altitude_lower: + value: 0 + units: M + reference: SFC + altitude_upper: + value: 100 + units: M + reference: SFC + start_time: + start_of_test: { } + end_time: + offset_from: + starting_from: + next_day: + time_zone: Europe/Zurich + starting_from: + start_of_test: { } + days_of_the_week: [ "Mo", "Fr" ] + offset: 12h + expected_result: Block + - geospatial_check_id: TEST_002 + requirement_ids: + - REQ_001 + - REQ_003 + - REQ_004 + description: The second test step defined by the test designer + operation_rule_set: Rules1 + restriction_source: ThisRegulator + volumes: + - outline_circle: + center: + lng: 7.4774 + lat: 46.9749 + radius: value: 100 units: M - reference: SFC - start_time: - start_of_test: {} - end_time: - offset_from: - starting_from: - next_day: - time_zone: Europe/Zurich - starting_from: - start_of_test: {} - days_of_the_week: ["Mo", "Fr"] - offset: 12h - expected_result: Block - - geospatial_check_id: TEST_002 - requirement_ids: - - REQ_001 - - REQ_003 - - REQ_004 - description: The second test step defined by the test designer - operation_rule_set: Rules1 - restriction_source: ThisRegulator - volumes: - - outline_circle: - center: - lng: 7.4774 - lat: 46.9749 - radius: - value: 100 - units: M - altitude_lower: - value: 50 + altitude_lower: + value: 50 + units: M + reference: SFC + altitude_upper: + value: 5000 + units: FT + reference: W84 + start_time: + next_day: + time_zone: Europe/Zurich + starting_from: + offset_from: + starting_from: + start_of_test: { } + offset: 12h + use_timezone: +01:00 + duration: 5m + expected_result: Advise + - geospatial_check_id: TEST_002 + requirement_ids: + - REQ_001 + - REQ_003 + - REQ_004 + description: The second test step defined by the test designer + operation_rule_set: Rules1 + restriction_source: ThisRegulator + volumes: + - outline_circle: + center: + lng: 7.4774 + lat: 46.9749 + radius: + value: 100 units: M - reference: SFC - altitude_upper: - value: 5000 - units: FT - reference: W84 - start_time: - next_day: - time_zone: Europe/Zurich - starting_from: - offset_from: - starting_from: - start_of_test: {} - offset: 12h - use_timezone: +01:00 - duration: 5m - expected_result: Advise - - geospatial_check_id: TEST_002 - requirement_ids: - - REQ_001 - - REQ_003 - - REQ_004 - description: The second test step defined by the test designer - operation_rule_set: Rules1 - restriction_source: ThisRegulator - volumes: - - outline_circle: - center: + altitude_upper: + value: 400 + units: FT + reference: SFC + end_time: + next_sun_position: + elevation_deg: -0.833 # Sunset + observed_from: lng: 7.4774 lat: 46.9749 - radius: - value: 100 - units: M - altitude_upper: - value: 400 - units: FT - reference: SFC - end_time: - next_sun_position: - elevation_deg: -0.833 # Sunset - observed_from: - lng: 7.4774 - lat: 46.9749 - starting_from: - offset_from: - starting_from: - next_day: - time_zone: Europe/Zurich - starting_from: - start_of_test: {} - offset: 12h - duration: 5m - expected_result: Advise -common: - $ref: 'environment.yaml#/common' + starting_from: + offset_from: + starting_from: + next_day: + time_zone: Europe/Zurich + starting_from: + start_of_test: { } + offset: 12h + duration: 5m + expected_result: Advise + +# ===== mock_uss behavioral control ===== + +locality_che: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.interuss.mock_uss.locality.LocalityResource + specification: + locality_code: CHE -mock_uss_instances: - $ref: 'environment.yaml#/mock_uss_instances' - locality_che: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.mock_uss.locality.LocalityResource - specification: - locality_code: CHE +# ===== System versioning ===== -uspace_versioning: - $ref: 'environment.yaml#/scd_version_providers' - uspace_system_identity: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.versioning.SystemIdentityResource - specification: - system_identity: uspace.ussp +uspace_system_identity: + $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json + resource_type: resources.versioning.SystemIdentityResource + specification: + system_identity: uspace.ussp diff --git a/monitoring/uss_qualifier/configurations/dev/message_signing.yaml b/monitoring/uss_qualifier/configurations/dev/message_signing.yaml new file mode 100644 index 0000000000..ea33cc7af7 --- /dev/null +++ b/monitoring/uss_qualifier/configurations/dev/message_signing.yaml @@ -0,0 +1,54 @@ +v1: + test_run: + resources: + resource_declarations: + che_conflicting_flights: {$ref: 'library/resources.yaml#/che_conflicting_flights'} + che_invalid_flight_intents: {$ref: 'library/resources.yaml#/che_invalid_flight_intents'} + combination_selector: + resource_type: resources.flight_planning.FlightPlannerCombinationSelectorResource + specification: + must_include: + - mock_uss + maximum_roles: + mock_uss: 1 + + utm_auth: {$ref: 'library/environment.yaml#/utm_auth'} + scd_dss: {$ref: 'library/environment.yaml#/scd_dss'} + flight_planners: + resource_type: resources.flight_planning.FlightPlannersResource + dependencies: + auth_adapter: utm_auth + specification: + flight_planners: + - participant_id: uss1 + injection_base_url: http://host.docker.internal:8074/scdsc + - participant_id: uss2 + injection_base_url: http://host.docker.internal:8074/scdsc + - participant_id: mock_uss + injection_base_url: http://host.docker.internal:8074/scdsc + mock_uss: + resource_type: resources.interuss.mock_uss.client.MockUSSResource + dependencies: + auth_adapter: utm_auth + specification: + participant_id: mock_uss + mock_uss_base_url: http://host.docker.internal:8074 + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.all_flight_planners + - v1.test_run.resources.resource_declarations.scd_dss + - v1.test_run.resources.resource_declarations.mock_uss_instance_uss1 + action: + test_suite: + suite_type: suites.faa.uft.message_signing + resources: + mock_uss: mock_uss + flight_planners: flight_planners + combination_selector: combination_selector + conflicting_flights: che_conflicting_flights + priority_preemption_flights: che_conflicting_flights + dss: scd_dss + + artifacts: + report: + report_path: output/report_message_signing.json diff --git a/monitoring/uss_qualifier/configurations/dev/netrid_v19.yaml b/monitoring/uss_qualifier/configurations/dev/netrid_v19.yaml index 58e5e85459..65e3b32062 100644 --- a/monitoring/uss_qualifier/configurations/dev/netrid_v19.yaml +++ b/monitoring/uss_qualifier/configurations/dev/netrid_v19.yaml @@ -1,42 +1,56 @@ $content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json v1: - test_run: + test_run: + resources: + resource_declarations: + kentland_flights_data: {$ref: 'library/resources.yaml#/kentland_flights_data'} + netrid_observation_evaluation_configuration: {$ref: 'library/resources.yaml#/netrid_observation_evaluation_configuration'} + id_generator: {$ref: 'library/resources.yaml#/id_generator'} + kentland_service_area: {$ref: 'library/resources.yaml#/kentland_service_area'} + au_problematically_big_area: {$ref: 'library/resources.yaml#/au_problematically_big_area'} + + utm_auth: {$ref: 'library/environment.yaml#/utm_auth'} + netrid_service_providers_v19: {$ref: 'library/environment.yaml#/netrid_service_providers_v19'} + netrid_observers_v19: {$ref: 'library/environment.yaml#/netrid_observers_v19'} + netrid_dss_instances_v19: {$ref: 'library/environment.yaml#/netrid_dss_instances_v19'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.netrid_service_providers_v19 + - v1.test_run.resources.resource_declarations.netrid_observers_v19 + - v1.test_run.resources.resource_declarations.netrid_dss_instances_v19 + action: + test_suite: + suite_type: suites.astm.netrid.f3411_19 resources: - resource_declarations: - $ref: ./library/resources.yaml#/all - action: - test_suite: - suite_type: suites.astm.netrid.f3411_19 - resources: - flights_data: kentland_flights_data - service_providers: netrid_service_providers_v19 - observers: netrid_observers_v19 - evaluation_configuration: netrid_observation_evaluation_configuration - dss_instances: netrid_dss_instances_v19 - id_generator: id_generator - service_area: service_area - problematically_big_area: problematically_big_area - artifacts: - report: - report_path: output/report_netrid_v19.json - tested_roles: - report_path: output/tested_roles_netrid_v19 - tested_requirements: - output_path: output/tested_requirements_f3411v19 - requirement_collections: - sp_dp_dss: - requirement_sets: - - astm.f3411.v19.service_provider#Tested by automated tests - - astm.f3411.v19.display_provider#Automated verification - - astm.f3411.v19.dss_provider - sp_dss: - requirement_sets: - - astm.f3411.v19.service_provider#Tested by automated tests - - astm.f3411.v19.dss_provider - participant_requirements: - uss1: sp_dp_dss - uss2: sp_dss - sequence_view: - output_path: output/sequence_netrid_v19 - validation: - $ref: ./library/validation.yaml#/normal_test + flights_data: kentland_flights_data + service_providers: netrid_service_providers_v19 + observers: netrid_observers_v19 + evaluation_configuration: netrid_observation_evaluation_configuration + dss_instances: netrid_dss_instances_v19 + id_generator: id_generator + service_area: kentland_service_area + problematically_big_area: au_problematically_big_area + artifacts: + report: + report_path: output/report_netrid_v19.json + tested_roles: + report_path: output/tested_roles_netrid_v19 + tested_requirements: + output_path: output/tested_requirements_f3411v19 + requirement_collections: + sp_dp_dss: + requirement_sets: + - astm.f3411.v19.service_provider#Tested by automated tests + - astm.f3411.v19.display_provider#Automated verification + - astm.f3411.v19.dss_provider + sp_dss: + requirement_sets: + - astm.f3411.v19.service_provider#Tested by automated tests + - astm.f3411.v19.dss_provider + participant_requirements: + uss1: sp_dp_dss + uss2: sp_dss + sequence_view: + output_path: output/sequence_netrid_v19 + validation: + $ref: ./library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/netrid_v22a.yaml b/monitoring/uss_qualifier/configurations/dev/netrid_v22a.yaml index 0405c07c31..7d919e2ebd 100644 --- a/monitoring/uss_qualifier/configurations/dev/netrid_v22a.yaml +++ b/monitoring/uss_qualifier/configurations/dev/netrid_v22a.yaml @@ -1,42 +1,56 @@ $content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json v1: - test_run: + test_run: + resources: + resource_declarations: + kentland_flights_data: {$ref: 'library/resources.yaml#/kentland_flights_data'} + netrid_observation_evaluation_configuration: {$ref: 'library/resources.yaml#/netrid_observation_evaluation_configuration'} + id_generator: {$ref: 'library/resources.yaml#/id_generator'} + kentland_service_area: {$ref: 'library/resources.yaml#/kentland_service_area'} + au_problematically_big_area: {$ref: 'library/resources.yaml#/au_problematically_big_area'} + + utm_auth: {$ref: 'library/environment.yaml#/utm_auth'} + netrid_service_providers_v22a: {$ref: 'library/environment.yaml#/netrid_service_providers_v22a'} + netrid_observers_v22a: {$ref: 'library/environment.yaml#/netrid_observers_v22a'} + netrid_dss_instances_v22a: {$ref: 'library/environment.yaml#/netrid_dss_instances_v22a'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.netrid_service_providers_v22a + - v1.test_run.resources.resource_declarations.netrid_observers_v22a + - v1.test_run.resources.resource_declarations.netrid_dss_instances_v22a + action: + test_suite: + suite_type: suites.astm.netrid.f3411_22a resources: - resource_declarations: - $ref: ./library/resources.yaml#/all - action: - test_suite: - suite_type: suites.astm.netrid.f3411_22a - resources: - flights_data: kentland_flights_data - service_providers: netrid_service_providers_v22a - observers: netrid_observers_v22a - evaluation_configuration: netrid_observation_evaluation_configuration - dss_instances: netrid_dss_instances_v22a - id_generator: id_generator - service_area: service_area - problematically_big_area: problematically_big_area - artifacts: - report: - report_path: output/report_netrid_v22a.json - tested_roles: - report_path: output/tested_roles_netrid_v22a - tested_requirements: - output_path: output/tested_requirements_f3411v22a - requirement_collections: - sp_dp_dss: - requirement_sets: - - astm.f3411.v22a.service_provider#Mandatory requirements - - astm.f3411.v22a.display_provider#Mandatory requirements - - astm.f3411.v22a.dss_provider - sp_dss: - requirement_sets: - - astm.f3411.v22a.service_provider#Mandatory requirements - - astm.f3411.v22a.dss_provider - participant_requirements: - uss1: sp_dp_dss - uss2: sp_dss - sequence_view: - output_path: output/sequence_netrid_v22a - validation: - $ref: ./library/validation.yaml#/normal_test + flights_data: kentland_flights_data + service_providers: netrid_service_providers_v22a + observers: netrid_observers_v22a + evaluation_configuration: netrid_observation_evaluation_configuration + dss_instances: netrid_dss_instances_v22a + id_generator: id_generator + service_area: kentland_service_area + problematically_big_area: au_problematically_big_area + artifacts: + report: + report_path: output/report_netrid_v22a.json + tested_roles: + report_path: output/tested_roles_netrid_v22a + tested_requirements: + output_path: output/tested_requirements_f3411v22a + requirement_collections: + sp_dp_dss: + requirement_sets: + - astm.f3411.v22a.service_provider#Mandatory requirements + - astm.f3411.v22a.display_provider#Mandatory requirements + - astm.f3411.v22a.dss_provider + sp_dss: + requirement_sets: + - astm.f3411.v22a.service_provider#Mandatory requirements + - astm.f3411.v22a.dss_provider + participant_requirements: + uss1: sp_dp_dss + uss2: sp_dss + sequence_view: + output_path: output/sequence_netrid_v22a + validation: + $ref: ./library/validation.yaml#/normal_test diff --git a/monitoring/uss_qualifier/configurations/dev/non_docker/environment.yaml b/monitoring/uss_qualifier/configurations/dev/non_docker/environment.yaml deleted file mode 100644 index ed8667e072..0000000000 --- a/monitoring/uss_qualifier/configurations/dev/non_docker/environment.yaml +++ /dev/null @@ -1,179 +0,0 @@ -# The resources in this file describe the system/environment under test and should not change the test being run. - -non_baseline_inputs: - $ref: '../library/environment.yaml#/non_baseline_inputs' - -common: - $ref: '../library/environment.yaml#/common' - -net_rid: - netrid_service_providers_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDServiceProviders - dependencies: - auth_adapter: utm_auth - specification: - service_providers: - - participant_id: uss2 - injection_base_url: http://localhost:8071/ridsp/injection - local_debug: true - netrid_service_providers_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDServiceProviders - dependencies: - auth_adapter: utm_auth - specification: - service_providers: - - participant_id: uss1 - injection_base_url: http://localhost:8081/ridsp/injection - local_debug: true - netrid_observers_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDObserversResource - dependencies: - auth_adapter: utm_auth - specification: - observers: - - participant_id: uss3 - observation_base_url: http://localhost:8073/riddp/observation - local_debug: true - netrid_observers_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.netrid.NetRIDObserversResource - dependencies: - auth_adapter: utm_auth - specification: - observers: - - participant_id: uss1 - observation_base_url: http://localhost:8083/riddp/observation - local_debug: true - netrid_dss_instances_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-19 - base_url: http://localhost:8082 - has_private_address: true - - participant_id: uss2 - rid_version: F3411-19 - base_url: http://localhost:8082 - has_private_address: true - netrid_dss_instances_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - rid_version: F3411-22a - base_url: http://localhost:8082/rid/v2 - has_private_address: true - - participant_id: uss2 - rid_version: F3411-22a - base_url: http://localhost:8082/rid/v2 - has_private_address: true - netrid_dss_instance_v19: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - rid_version: F3411-19 - base_url: http://localhost:8082 - has_private_address: true - netrid_dss_instance_v22a: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3411.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - rid_version: F3411-22a - base_url: http://localhost:8082/rid/v2 - has_private_address: true - -f3548: - flight_planners: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannersResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planners: - # uss1 is the mock_uss directly exposing scdsc functionality - - participant_id: uss1 - injection_base_url: http://localhost:8074/scdsc - local_debug: true - - # The atproxy has been disabled since it is suspected to be responsible of issue #28. Replaced by another simple mock_uss - # # uss2 uses atproxy, with requests being fulfilled by mock_uss with atproxy_client functionality enabled - # - participant_id: uss2 - # injection_base_url: http://host.docker.internal:8075/scd - - # uss2 is the mock_uss directly exposing scdsc functionality - - participant_id: uss2 - injection_base_url: http://localhost:8094/scdsc - local_debug: true - scd_dss: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3548.v21.DSSInstanceResource - dependencies: - auth_adapter: utm_auth - specification: - participant_id: uss1 - base_url: http://localhost:8082 - has_private_address: true - scd_dss_instances: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.astm.f3548.v21.DSSInstancesResource - dependencies: - auth_adapter: utm_auth - specification: - dss_instances: - - participant_id: uss1 - base_url: http://localhost:8082 - has_private_address: true - - participant_id: uss2 - base_url: http://localhost:8082 - has_private_address: true - -f3548_single_scenario: - uss1: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannerResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planner: - participant_id: uss1 - injection_base_url: http://localhost:8074/scdsc - local_debug: true - uss2: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.flight_planning.FlightPlannerResource - dependencies: - auth_adapter: utm_auth - specification: - flight_planner: - participant_id: uss2 - injection_base_url: http://localhost:8094/scdsc - local_debug: true - -mock_uss_instances: - mock_uss_instances_scdsc: - $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json - resource_type: resources.interuss.mock_uss.client.MockUSSsResource - dependencies: - auth_adapter: utm_auth - specification: - instances: - - mock_uss_base_url: http://localhost:8074 - participant_id: uss1 - - mock_uss_base_url: http://localhost:8094 - participant_id: uss2 diff --git a/monitoring/uss_qualifier/configurations/dev/uspace.yaml b/monitoring/uss_qualifier/configurations/dev/uspace.yaml index 3406b8b704..eac7881a40 100644 --- a/monitoring/uss_qualifier/configurations/dev/uspace.yaml +++ b/monitoring/uss_qualifier/configurations/dev/uspace.yaml @@ -1,10 +1,38 @@ $content_schema: monitoring/uss_qualifier/configurations/configuration/USSQualifierConfiguration.json v1: test_run: - $ref: ./library/environment.yaml#/non_baseline_inputs resources: resource_declarations: - $ref: ./library/resources.yaml#/all + locality_che: {$ref: 'library/resources.yaml#/locality_che'} + uspace_system_identity: {$ref: 'library/resources.yaml#/uspace_system_identity'} + che_conflicting_flights: {$ref: 'library/resources.yaml#/che_conflicting_flights'} + che_invalid_flight_intents: {$ref: 'library/resources.yaml#/che_invalid_flight_intents'} + che_invalid_flight_auth_flights: {$ref: 'library/resources.yaml#/che_invalid_flight_auth_flights'} + foca_flights_data: {$ref: 'library/resources.yaml#/foca_flights_data'} + netrid_observation_evaluation_configuration: {$ref: 'library/resources.yaml#/netrid_observation_evaluation_configuration'} + id_generator: {$ref: 'library/resources.yaml#/id_generator'} + kentland_service_area: {$ref: 'library/resources.yaml#/kentland_service_area'} + au_problematically_big_area: {$ref: 'library/resources.yaml#/au_problematically_big_area'} + + utm_auth: {$ref: 'library/environment.yaml#/utm_auth'} + mock_uss_instances_scdsc: {$ref: 'library/environment.yaml#/mock_uss_instances_scdsc'} + scd_version_providers: {$ref: 'library/environment.yaml#/scd_version_providers'} + all_flight_planners: {$ref: 'library/environment.yaml#/all_flight_planners'} + scd_dss: {$ref: 'library/environment.yaml#/scd_dss'} + scd_dss_instances: {$ref: 'library/environment.yaml#/scd_dss_instances'} + netrid_service_providers_v22a: {$ref: 'library/environment.yaml#/netrid_service_providers_v22a'} + netrid_observers_v22a: {$ref: 'library/environment.yaml#/netrid_observers_v22a'} + netrid_dss_instances_v22a: {$ref: 'library/environment.yaml#/netrid_dss_instances_v22a'} + non_baseline_inputs: + - v1.test_run.resources.resource_declarations.utm_auth + - v1.test_run.resources.resource_declarations.mock_uss_instances_scdsc + - v1.test_run.resources.resource_declarations.scd_version_providers + - v1.test_run.resources.resource_declarations.all_flight_planners + - v1.test_run.resources.resource_declarations.scd_dss + - v1.test_run.resources.resource_declarations.scd_dss_instances + - v1.test_run.resources.resource_declarations.netrid_service_providers_v22a + - v1.test_run.resources.resource_declarations.netrid_observers_v22a + - v1.test_run.resources.resource_declarations.netrid_dss_instances_v22a action: action_generator: generator_type: action_generators.interuss.mock_uss.WithLocality @@ -12,14 +40,14 @@ v1: mock_uss_instances: mock_uss_instances_scdsc locality: locality_che - version_providers: version_providers + version_providers: scd_version_providers system_identity: uspace_system_identity - conflicting_flights: conflicting_flights - priority_preemption_flights: priority_preemption_flights - invalid_flight_intents: invalid_flight_intents - invalid_flight_auth_flights: invalid_flight_auth_flights - flight_planners: flight_planners + conflicting_flights: che_conflicting_flights + priority_preemption_flights: che_conflicting_flights + invalid_flight_intents: che_invalid_flight_intents + invalid_flight_auth_flights: che_invalid_flight_auth_flights + flight_planners: all_flight_planners scd_dss: scd_dss scd_dss_instances: scd_dss_instances @@ -29,8 +57,8 @@ v1: evaluation_configuration: netrid_observation_evaluation_configuration netrid_dss_instances: netrid_dss_instances_v22a id_generator: id_generator - service_area: service_area - problematically_big_area: problematically_big_area + service_area: kentland_service_area + problematically_big_area: au_problematically_big_area specification: mock_uss_instances_source: mock_uss_instances locality_source: locality @@ -57,7 +85,6 @@ v1: id_generator: id_generator service_area: service_area problematically_big_area: problematically_big_area - on_failure: Continue artifacts: tested_roles: report_path: output/tested_roles_uspace diff --git a/monitoring/uss_qualifier/reports/sequence_view.py b/monitoring/uss_qualifier/reports/sequence_view.py index e56ae9dd93..cba2d75efa 100644 --- a/monitoring/uss_qualifier/reports/sequence_view.py +++ b/monitoring/uss_qualifier/reports/sequence_view.py @@ -297,8 +297,8 @@ def append_notes(new_notes): events.append(Event(query=query)) all_events.append(events[-1]) participant_id = ( - query.server_id - if "server_id" in query and query.server_id + query.participant_id + if "participant_id" in query and query.participant_id else UNATTRIBUTED_PARTICIPANT ) p = scenario_participants.get(participant_id, TestedParticipant()) diff --git a/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html b/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html index 06c3db54af..1b338dbb52 100644 --- a/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html +++ b/monitoring/uss_qualifier/reports/templates/sequence_view/scenario.html @@ -166,7 +166,7 @@

{{ test_scenario.type }}

{% set collapsible.queries = collapsible.queries + [query_id] %} {% for participant_id in all_participants %} - {% if (participant_id != UNATTRIBUTED_PARTICIPANT and participant_id == event.query.get("server_id", None)) or (participant_id == UNATTRIBUTED_PARTICIPANT and not event.query.get("server_id", None)) %} + {% if (participant_id != UNATTRIBUTED_PARTICIPANT and participant_id == event.query.get("participant_id", None)) or (participant_id == UNATTRIBUTED_PARTICIPANT and not event.query.get("participant_id", None)) %} 🌐 {% else %} diff --git a/monitoring/uss_qualifier/reports/tested_requirements.py b/monitoring/uss_qualifier/reports/tested_requirements.py index c918eb854c..2ec61863df 100644 --- a/monitoring/uss_qualifier/reports/tested_requirements.py +++ b/monitoring/uss_qualifier/reports/tested_requirements.py @@ -517,22 +517,22 @@ def _populate_breakdown_with_action_declaration( load_dict_with_references(action.test_suite.suite_type), TestSuiteDefinition, ) - for action in suite_def.actions: - _populate_breakdown_with_action_declaration(breakdown, action, req_set) + for a in suite_def.actions: + _populate_breakdown_with_action_declaration(breakdown, a, req_set) elif ( "suite_definition" in action.test_suite and action.test_suite.suite_definition ): - for action in action.test_suite.suite_definition: - _populate_breakdown_with_action_declaration(breakdown, action, req_set) + for a in action.test_suite.suite_definition.actions: + _populate_breakdown_with_action_declaration(breakdown, a, req_set) else: raise ValueError(f"Test suite action missing suite type or definition") elif action_type == ActionType.ActionGenerator: potential_actions = list_potential_actions_for_action_generator_definition( action.action_generator ) - for action in potential_actions: - _populate_breakdown_with_action_declaration(breakdown, action, req_set) + for a in potential_actions: + _populate_breakdown_with_action_declaration(breakdown, a, req_set) else: raise NotImplementedError(f"Unsupported test suite action type: {action_type}") diff --git a/monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py b/monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py index c0b99aac18..b416ad3121 100644 --- a/monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py +++ b/monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py @@ -66,7 +66,7 @@ def find_op_intent( url, scope=SCOPE_SC, json=req, - server_id=self.participant_id, + participant_id=self.participant_id, ) if query.status_code != 200: result = None @@ -81,7 +81,7 @@ def get_full_op_intent( ) -> Tuple[OperationalIntent, fetch.Query]: url = f"{op_intent_ref.uss_base_url}/uss/v1/operational_intents/{op_intent_ref.id}" query = fetch.query_and_describe( - self.client, "GET", url, scope=SCOPE_SC, server_id=self.participant_id + self.client, "GET", url, scope=SCOPE_SC, participant_id=self.participant_id ) if query.status_code != 200: result = None diff --git a/monitoring/uss_qualifier/resources/interuss/mock_uss/client.py b/monitoring/uss_qualifier/resources/interuss/mock_uss/client.py index e70ab45d10..2c6fd7f534 100644 --- a/monitoring/uss_qualifier/resources/interuss/mock_uss/client.py +++ b/monitoring/uss_qualifier/resources/interuss/mock_uss/client.py @@ -38,7 +38,7 @@ def get_status(self) -> fetch.Query: "GET", "/scdsc/v1/status", scope=SCOPE_SCD_QUALIFIER_INJECT, - server_id=self.participant_id, + participant_id=self.participant_id, ) def get_locality(self) -> Tuple[Optional[LocalityCode], fetch.Query]: @@ -46,7 +46,7 @@ def get_locality(self) -> Tuple[Optional[LocalityCode], fetch.Query]: self.session, "GET", "/configuration/locality", - server_id=self.participant_id, + participant_id=self.participant_id, ) if query.status_code != 200: return None, query @@ -62,7 +62,7 @@ def set_locality(self, locality_code: LocalityCode) -> fetch.Query: "PUT", "/configuration/locality", scope=MOCK_USS_CONFIG_SCOPE, - server_id=self.participant_id, + participant_id=self.participant_id, json=PutLocalityRequest(locality_code=locality_code), ) diff --git a/monitoring/uss_qualifier/resources/netrid/observers.py b/monitoring/uss_qualifier/resources/netrid/observers.py index 2448df2c79..b172672225 100644 --- a/monitoring/uss_qualifier/resources/netrid/observers.py +++ b/monitoring/uss_qualifier/resources/netrid/observers.py @@ -49,7 +49,7 @@ def observe_system( # TODO replace with 'uas_standards.interuss.automated_testing.rid.v1.constants.Scope.Observe' once # the standard is updated with https://github.com/interuss/uas_standards/pull/11/files scope="dss.read.identification_service_areas", - server_id=self.participant_id, + participant_id=self.participant_id, ) try: result = ( @@ -74,10 +74,10 @@ def observe_flight_details( # TODO replace with 'uas_standards.interuss.automated_testing.rid.v1.constants.Scope.Observe' once # the standard is updated with https://github.com/interuss/uas_standards/pull/11/files scope="dss.read.identification_service_areas", - server_id=self.participant_id, + participant_id=self.participant_id, ) # Record query metadata for later use in the aggregate checks - query.server_id = self.participant_id + query.participant_id = self.participant_id query.query_type = QueryType.flight_details(rid_version) try: result = ( diff --git a/monitoring/uss_qualifier/resources/netrid/service_providers.py b/monitoring/uss_qualifier/resources/netrid/service_providers.py index 76c02a981f..cdbc5a36ea 100644 --- a/monitoring/uss_qualifier/resources/netrid/service_providers.py +++ b/monitoring/uss_qualifier/resources/netrid/service_providers.py @@ -41,39 +41,41 @@ class NetRIDServiceProvidersSpecification(ImplicitDict): class NetRIDServiceProvider(object): participant_id: str - base_url: str - client: infrastructure.UTMClientSession + injection_base_url: str + injection_client: infrastructure.UTMClientSession local_debug: bool def __init__( self, participant_id: str, - base_url: str, + injection_base_url: str, auth_adapter: infrastructure.AuthAdapter, local_debug: bool, ): self.participant_id = participant_id - self.base_url = base_url - self.client = infrastructure.UTMClientSession(base_url, auth_adapter) + self.injection_base_url = injection_base_url + self.injection_client = infrastructure.UTMClientSession( + injection_base_url, auth_adapter + ) self.local_debug = local_debug def submit_test(self, request: CreateTestParameters, test_id: str) -> fetch.Query: return fetch.query_and_describe( - self.client, + self.injection_client, "PUT", url=f"/tests/{test_id}", json=request, scope=SCOPE_RID_QUALIFIER_INJECT, - server_id=self.participant_id, + participant_id=self.participant_id, ) def delete_test(self, test_id: str, version: str) -> fetch.Query: return fetch.query_and_describe( - self.client, + self.injection_client, "DELETE", url=f"/tests/{test_id}/{version}", scope=SCOPE_RID_QUALIFIER_INJECT, - server_id=self.participant_id, + participant_id=self.participant_id, ) @@ -87,10 +89,10 @@ def __init__( ): self.service_providers = [ NetRIDServiceProvider( - s.participant_id, - s.injection_base_url, - auth_adapter.adapter, - s.get("local_debug", False), + participant_id=s.participant_id, + injection_base_url=s.injection_base_url, + auth_adapter=auth_adapter.adapter, + local_debug=s.get("local_debug", False), ) for s in specification.service_providers ] diff --git a/monitoring/uss_qualifier/run_locally.sh b/monitoring/uss_qualifier/run_locally.sh index 224ee228db..4ac41fb7a5 100755 --- a/monitoring/uss_qualifier/run_locally.sh +++ b/monitoring/uss_qualifier/run_locally.sh @@ -26,12 +26,12 @@ OTHER_ARGS=${@:2} if [ "$CONFIG_NAME" == "ALL" ]; then CONFIG_NAME="\ configurations.dev.noop,\ -configurations.dev.dss_probing,\ configurations.dev.geoawareness_cis,\ configurations.dev.generate_rid_test_data,\ configurations.dev.geospatial_comprehension,\ configurations.dev.general_flight_auth,\ -configurations.dev.f3548,\ +configurations.dev.message_signing,\ +configurations.dev.dss_probing,\ configurations.dev.f3548_self_contained,\ configurations.dev.netrid_v22a,\ configurations.dev.netrid_v19,\ diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/aggregate_checks.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/aggregate_checks.py index a284f4465e..65cd73015d 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/aggregate_checks.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/aggregate_checks.py @@ -51,8 +51,9 @@ def __init__( # identify SPs and observers by their base URL self._participants_by_base_url.update( - {sp.base_url: sp.participant_id for sp in self._service_providers} + {sp.injection_base_url: sp.participant_id for sp in self._service_providers} ) + self._participants_by_base_url.update( {dp.base_url: dp.participant_id for dp in self._observers} ) @@ -85,12 +86,12 @@ def __init__( break # Only consider queries with the participant/server explicitly identified - if query.has_field_with_value("server_id"): + if query.has_field_with_value("participant_id"): participant_queries = self._queries_by_participant.get( - query.server_id, [] + query.participant_id, [] ) participant_queries.append(query) - self._queries_by_participant[query.server_id] = participant_queries + self._queries_by_participant[query.participant_id] = participant_queries def run(self): self.begin_test_scenario() @@ -101,7 +102,7 @@ def run(self): for sp in self._service_providers: self.record_note( "service_providers", - f"configured service providers: {sp.participant_id} - {sp.base_url}", + f"configured service providers: {sp.participant_id} - {sp.injection_base_url}", ) for o in self._observers: @@ -151,7 +152,7 @@ def _verify_https_everywhere(self): unattr_queries = [ query.request.url for query in self._queries - if query.get("server_id") is None + if query.get("participant_id") is None ] if len(unattr_queries) > 0: self.record_note( diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_simple.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_simple.py index dd347acddc..c1d6dc5ae1 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_simple.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_simple.py @@ -76,7 +76,7 @@ def _delete_isa_if_exists(self): self._isa_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self.record_query(fetched.query) with self.check("Successful ISA query", [self._dss.participant_id]) as check: @@ -94,7 +94,7 @@ def _delete_isa_if_exists(self): fetched.isa.version, self._dss.rid_version, self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self.record_query(deleted.dss_query.query) for subscriber_id, notification in deleted.notifications.items(): diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_validation.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_validation.py index 3616dfec5c..8a4f355856 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_validation.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/isa_validation.py @@ -111,7 +111,7 @@ def _delete_isa_if_exists(self): isa_id=self._isa_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss_wrapper.participant_id, + participant_id=self._dss_wrapper.participant_id, ) def _isa_huge_area_check(self) -> (str, Dict[str, Any]): diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/utils.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/utils.py index c108b93f96..ea314377e9 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/utils.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/utils.py @@ -13,21 +13,21 @@ def delete_isa_if_exists( isa_id: str, rid_version: RIDVersion, session: UTMClientSession, - server_id: Optional[str] = None, + participant_id: Optional[str] = None, ): fetched = fetch.isa( isa_id, rid_version=rid_version, session=session, - server_id=server_id, + participant_id=participant_id, ) scenario.record_query(fetched.query) - with scenario.check("Successful ISA query", [server_id]) as check: + with scenario.check("Successful ISA query", [participant_id]) as check: if not fetched.success and fetched.status_code != 404: check.record_failed( "ISA information could not be retrieved", Severity.High, - f"{server_id} DSS instance returned {fetched.status_code} when queried for ISA {isa_id}", + f"{participant_id} DSS instance returned {fetched.status_code} when queried for ISA {isa_id}", query_timestamps=[fetched.query.request.timestamp], ) @@ -37,17 +37,17 @@ def delete_isa_if_exists( fetched.isa.version, rid_version, session, - server_id=server_id, + participant_id=participant_id, ) scenario.record_query(deleted.dss_query.query) for subscriber_id, notification in deleted.notifications.items(): scenario.record_query(notification.query) - with scenario.check("Removed pre-existing ISA", [server_id]) as check: + with scenario.check("Removed pre-existing ISA", [participant_id]) as check: if not deleted.dss_query.success: check.record_failed( "Could not delete pre-existing ISA", Severity.High, - f"Attempting to delete ISA {isa_id} from the {server_id} DSS returned error {deleted.dss_query.status_code}", + f"Attempting to delete ISA {isa_id} from the {participant_id} DSS returned error {deleted.dss_query.status_code}", query_timestamps=[deleted.dss_query.query.request.timestamp], ) for subscriber_url, notification in deleted.notifications.items(): diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/misbehavior.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/misbehavior.py index a6fada8caf..52280c88f4 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/misbehavior.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/misbehavior.py @@ -1,23 +1,14 @@ -import time import traceback -import uuid -from typing import List +from typing import List, Set -import arrow import s2sphere -from implicitdict import ImplicitDict -from loguru import logger from requests.exceptions import RequestException -from uas_standards.interuss.automated_testing.rid.v1.injection import ChangeTestResponse +from s2sphere import LatLngRect -from monitoring.monitorlib import fetch +from monitoring.monitorlib import auth from monitoring.monitorlib.fetch import rid from monitoring.monitorlib.infrastructure import UTMClientSession from monitoring.monitorlib.rid import RIDVersion -from monitoring.monitorlib.rid_automated_testing.injection_api import ( - CreateTestParameters, -) -from monitoring.monitorlib.rid_automated_testing.injection_api import TestFlight from monitoring.uss_qualifier.common_data_definitions import Severity from monitoring.uss_qualifier.resources.astm.f3411.dss import DSSInstancesResource from monitoring.uss_qualifier.resources.netrid import ( @@ -25,8 +16,10 @@ NetRIDServiceProviders, EvaluationConfigurationResource, ) -from monitoring.uss_qualifier.scenarios.astm.netrid import display_data_evaluator -from monitoring.uss_qualifier.scenarios.astm.netrid.common import nominal_behavior +from monitoring.uss_qualifier.scenarios.astm.netrid import ( + injection, + display_data_evaluator, +) from monitoring.uss_qualifier.scenarios.astm.netrid.injected_flight_collection import ( InjectedFlightCollection, ) @@ -48,6 +41,7 @@ class Misbehavior(GenericTestScenario): _flights_data: FlightDataResource _service_providers: NetRIDServiceProviders _evaluation_configuration: EvaluationConfigurationResource + _injected_flights: List[InjectedFlight] _injected_tests: List[InjectedTest] @@ -62,8 +56,6 @@ def __init__( self._flights_data = flights_data self._service_providers = service_providers self._evaluation_configuration = evaluation_configuration - self._injected_flights = [] - self._injected_tests = [] if len(dss_pool.dss_instances) == 0: raise ValueError( "The Misbehavior Scenario requires at least one DSS instance" @@ -94,140 +86,142 @@ def run(self): self.end_test_scenario() def _inject_flights(self): - ( - self._injected_flights, - self._injected_tests, - ) = nominal_behavior.inject_flights( - test_scenario=self, - flights_data=self._flights_data, - service_providers=self._service_providers, - evaluation_configuration=self._evaluation_configuration, - realtime_period=self._rid_version.realtime_period, + (self._injected_flights, self._injected_tests) = injection.inject_flights( + self, self._flights_data, self._service_providers ) def _poll_unauthenticated_during_flights(self): config = self._evaluation_configuration.configuration + virtual_observer = VirtualObserver( + injected_flights=InjectedFlightCollection(self._injected_flights), + repeat_query_rect_period=config.repeat_query_rect_period, + min_query_diagonal_m=config.min_query_diagonal, + relevant_past_data_period=self._rid_version.realtime_period + + config.max_propagation_latency.timedelta, + ) - t_end = self._virtual_observer.get_last_time_of_interest() - t_now = arrow.utcnow() + remaining_injection_ids = set( + inj_flight.flight.injection_id for inj_flight in self._injected_flights + ) - if t_now > t_end: - raise RuntimeError( - f"Cannot evaluate RID system: injected test flights ended at {t_end}, which is before now ({t_now})" - ) + def poll_fct(rect: LatLngRect) -> bool: + nonlocal remaining_injection_ids - logger.debug(f"Polling from {t_now} until {t_end}") - for f in self._injected_flights: - span = f.flight.get_span() - logger.debug( - f"Flight {f.uss_participant_id}/{f.flight.injection_id} {span[0].isoformat()} to {span[1].isoformat()}", - ) + tested_inj_ids = self._evaluate_and_test_authentication(rect) + remaining_injection_ids -= tested_inj_ids + + # interrupt polling if there are no more injection IDs to cover + return len(remaining_injection_ids) == 0 - t_next = arrow.utcnow() - dt = config.min_polling_interval.timedelta - while arrow.utcnow() < t_end: - # Evaluate the system at an instant in time for various areas - diagonals_m = [ + virtual_observer.start_polling( + config.min_polling_interval.timedelta, + [ self._rid_version.max_diagonal_km * 1000 + 500, # too large self._rid_version.max_diagonal_km * 1000 - 100, # clustered self._rid_version.max_details_diagonal_km * 1000 - 100, # details - ] - auth_tests = [] - for diagonal_m in diagonals_m: - rect = self._virtual_observer.get_query_rect(diagonal_m) - auth_tests.append(self._evaluate_and_test_authentication(rect)) - - # If we checked for all diagonals that flights queries are properly authenticated, - # we can stop polling - if all(auth_tests): - logger.debug( - "Authentication check is complete, ending polling now.", - ) - break - - # Wait until minimum polling interval elapses - while t_next < arrow.utcnow(): - t_next += dt - if t_next > t_end: - break - delay = t_next - arrow.utcnow() - if delay.total_seconds() > 0: - logger.debug( - f"Waiting {delay.total_seconds()} seconds before polling RID system again..." - ) - time.sleep(delay.total_seconds()) + ], + poll_fct, + ) def _evaluate_and_test_authentication( self, rect: s2sphere.LatLngRect, - ) -> bool: + ) -> Set[str]: """Queries all flights in the expected way, then repeats the queries to SPs without credentials. returns true once queries to SPS have been made without credentials. False otherwise, such as when no flights were yet returned by the authenticated queries. + + :returns: set of injection IDs that were encountered and tested """ - with self.check("Missing credentials") as check: - # We grab all flights from the SP's. This is authenticated - # and is expected to succeed - sp_observation = rid.all_flights( - rect, - include_recent_positions=True, - get_details=True, - rid_version=self._rid_version, - session=self._dss.client, - server_id=self._dss.participant_id, + # We grab all flights from the SP's (which we know how to reach by first querying the DSS). + # This is authenticated and is expected to succeed + sp_observation = rid.all_flights( + rect, + include_recent_positions=True, + get_details=True, + rid_version=self._rid_version, + session=self._dss.client, + dss_participant_id=self._dss.participant_id, + ) + + mapping_by_injection_id = ( + display_data_evaluator.map_fetched_to_injected_flights( + self._injected_flights, list(sp_observation.uss_flight_queries.values()) ) - # We fish out the queries that were used to grab the flights from the SP, - # and attempt to re-query without credentials. This should fail. + ) + for q in sp_observation.queries: + self.record_query(q) + for injection_id, mapping in mapping_by_injection_id.items(): + participant_id = mapping.injected_flight.uss_participant_id + flights_url = mapping.observed_flight.query.flights_url unauthenticated_session = UTMClientSession( - prefix_url=self._dss.client.get_prefix_url(), - auth_adapter=None, - timeout_seconds=self._dss.client.timeout_seconds, + flights_url, auth.NoAuth(aud_override="") ) - queries_to_repeat = list(sp_observation.uss_flight_queries.values()) + list( - sp_observation.uss_flight_details_queries.values() + self.record_note( + f"{participant_id}/{injection_id}/missing_credentials_queries", + f"Will attempt querying with missing credentials at flights URL {flights_url} for a flights list and {len(mapping.observed_flight.query.flights)} flight details.", ) - if len(queries_to_repeat) == 0: - logger.debug("no flights queries to repeat at this point.") - return False - - logger.debug( - f"about to repeat {len(queries_to_repeat)} flights queries without credentials" - ) + with self.check("Missing credentials", [participant_id]) as check: - # Attempt to re-query the flights and flight details URLs: - for fq in queries_to_repeat: - failed_q = fetch.query_and_describe( - client=unauthenticated_session, - verb=fq.query.request.method, - url=fq.query.request.url, - json=fq.query.request.json, - data=fq.query.request.body, - server_id=self._dss.participant_id, + # check uss flights query + uss_flights_query = rid.uss_flights( + flights_url, + rect, + True, + self._rid_version, + unauthenticated_session, + participant_id, ) - logger.info( - f"Repeating query to {fq.query.request.url} without credentials" - ) - server_id = fq.query.get("server_id", "unknown") - if failed_q.response.code not in [401, 403]: + self.record_query(uss_flights_query.query) + + if uss_flights_query.success: + check.record_failed( + "Unauthenticated request for flights to USS was fulfilled", + participants=[participant_id], + severity=Severity.Medium, + details=f"Queried flights on {flights_url} for USS {participant_id} with no credentials, expected a failure but got a success reply.", + ) + elif uss_flights_query.status_code != 401: check.record_failed( - "unauthenticated request was fulfilled", - participants=[server_id], - severity=Severity.MEDIUM, - details=f"queried flights on {fq.query.request.url} with no credentials, expected a failure but got a success reply", + "Unauthenticated request for flights failed with wrong HTTP code", + participants=[participant_id], + severity=Severity.Medium, + details=f"Queried flights on {flights_url} for USS {participant_id} with no credentials, expected an HTTP 401 but got an HTTP {uss_flights_query.status_code}.", ) - else: - logger.info( - f"participant with id {server_id} properly authenticated the request" + + # check flight details query + for flight in mapping.observed_flight.query.flights: + uss_flight_details_query = rid.flight_details( + flights_url, + flight.id, + False, + self._rid_version, + unauthenticated_session, + participant_id, ) - # Keep track of the failed queries, too - self.record_query(failed_q) + self.record_query(uss_flight_details_query.query) + + if uss_flight_details_query.success: + check.record_failed( + "Unauthenticated request for flight details to USS was fulfilled", + participants=[participant_id], + severity=Severity.Medium, + details=f"Queried flight details on {flights_url} for USS {participant_id} for flight {flight.id} with no credentials, expected a failure but got a success reply.", + ) + elif uss_flight_details_query.status_code != 401: + check.record_failed( + "Unauthenticated request for flight details failed with wrong HTTP code", + participants=[participant_id], + severity=Severity.Medium, + details=f"Queried flight details on {flights_url} for USS {participant_id} for flight {flight.id} with no credentials, expected an HTTP 401 but got an HTTP {uss_flight_details_query.status_code}.", + ) - return True + return set(mapping_by_injection_id.keys()) def cleanup(self): self.begin_cleanup() diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/common/nominal_behavior.py b/monitoring/uss_qualifier/scenarios/astm/netrid/common/nominal_behavior.py index 13b34650ad..0bbca48d26 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/common/nominal_behavior.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/common/nominal_behavior.py @@ -1,20 +1,10 @@ -import time import traceback -import uuid -from datetime import timedelta -from typing import List, Optional, Tuple +from typing import List, Optional -import arrow -from implicitdict import ImplicitDict -from loguru import logger from requests.exceptions import RequestException -from uas_standards.interuss.automated_testing.rid.v1.injection import ChangeTestResponse +from s2sphere import LatLngRect from monitoring.monitorlib.rid import RIDVersion -from monitoring.monitorlib.rid_automated_testing.injection_api import ( - CreateTestParameters, -) -from monitoring.monitorlib.rid_automated_testing.injection_api import TestFlight from monitoring.uss_qualifier.common_data_definitions import Severity from monitoring.uss_qualifier.resources.astm.f3411.dss import DSSInstancesResource from monitoring.uss_qualifier.resources.netrid import ( @@ -23,7 +13,10 @@ NetRIDObserversResource, EvaluationConfigurationResource, ) -from monitoring.uss_qualifier.scenarios.astm.netrid import display_data_evaluator +from monitoring.uss_qualifier.scenarios.astm.netrid import ( + display_data_evaluator, + injection, +) from monitoring.uss_qualifier.scenarios.astm.netrid.injected_flight_collection import ( InjectedFlightCollection, ) @@ -34,10 +27,7 @@ from monitoring.uss_qualifier.scenarios.astm.netrid.virtual_observer import ( VirtualObserver, ) -from monitoring.uss_qualifier.scenarios.scenario import ( - GenericTestScenario, - TestScenario, -) +from monitoring.uss_qualifier.scenarios.scenario import GenericTestScenario class NominalBehavior(GenericTestScenario): @@ -62,8 +52,6 @@ def __init__( self._service_providers = service_providers self._observers = observers self._evaluation_configuration = evaluation_configuration - self._injected_flights = [] - self._injected_tests = [] self._dss_pool = dss_pool @property @@ -86,18 +74,19 @@ def run(self): self.end_test_scenario() def _inject_flights(self): - (self._injected_flights, self._injected_tests) = inject_flights( - test_scenario=self, - flights_data=self._flights_data, - service_providers=self._service_providers, - evaluation_configuration=self._evaluation_configuration, - realtime_period=self._rid_version.realtime_period, + (self._injected_flights, self._injected_tests) = injection.inject_flights( + self, self._flights_data, self._service_providers ) def _poll_during_flights(self): config = self._evaluation_configuration.configuration - - # Evaluate observed RID system states + virtual_observer = VirtualObserver( + injected_flights=InjectedFlightCollection(self._injected_flights), + repeat_query_rect_period=config.repeat_query_rect_period, + min_query_diagonal_m=config.min_query_diagonal, + relevant_past_data_period=self._rid_version.realtime_period + + config.max_propagation_latency.timedelta, + ) evaluator = display_data_evaluator.RIDObservationEvaluator( self, self._injected_flights, @@ -106,46 +95,19 @@ def _poll_during_flights(self): self._dss_pool.dss_instances[0] if self._dss_pool else None, ) - t_end = self._virtual_observer.get_last_time_of_interest() - t_now = arrow.utcnow() - if t_now > t_end: - raise RuntimeError( - f"Cannot evaluate RID system: injected test flights ended at {t_end}, which is before now ({t_now})" - ) - - logger.debug(f"Polling from {t_now} until {t_end}") - for f in self._injected_flights: - span = f.flight.get_span() - logger.debug( - f"Flight {f.uss_participant_id}/{f.flight.injection_id} {span[0].isoformat()} to {span[1].isoformat()}", - ) + def poll_fct(rect: LatLngRect) -> bool: + evaluator.evaluate_system_instantaneously(self._observers.observers, rect) + return False - t_next = arrow.utcnow() - dt = config.min_polling_interval.timedelta - while arrow.utcnow() < t_end: - # Evaluate the system at an instant in time for various areas - diagonals_m = [ + virtual_observer.start_polling( + config.min_polling_interval.timedelta, + [ self._rid_version.max_diagonal_km * 1000 + 500, # too large self._rid_version.max_diagonal_km * 1000 - 100, # clustered self._rid_version.max_details_diagonal_km * 1000 - 100, # details - ] - for diagonal_m in diagonals_m: - rect = self._virtual_observer.get_query_rect(diagonal_m) - evaluator.evaluate_system_instantaneously( - self._observers.observers, rect - ) - - # Wait until minimum polling interval elapses - while t_next < arrow.utcnow(): - t_next += dt - if t_next > t_end: - break - delay = t_next - arrow.utcnow() - if delay.total_seconds() > 0: - logger.debug( - f"Waiting {delay.total_seconds()} seconds before polling RID system again..." - ) - time.sleep(delay.total_seconds()) + ], + poll_fct, + ) def cleanup(self): self.begin_cleanup() @@ -181,116 +143,3 @@ def cleanup(self): details=f"While trying to delete a test flight from {sp.participant_id}, encountered error:\n{stacktrace}", ) self.end_cleanup() - - -def inject_flights( - test_scenario: TestScenario, - flights_data: FlightDataResource, - service_providers: NetRIDServiceProviders, - evaluation_configuration: EvaluationConfigurationResource, - realtime_period: timedelta, -) -> Tuple[List[InjectedFlight], List[InjectedTest]]: - test_id = str(uuid.uuid4()) - test_flights = flights_data.get_test_flights() - service_providers = service_providers.service_providers - - injected_flights: List[InjectedFlight] = [] - injected_tests: List[InjectedTest] = [] - - if len(service_providers) > len(test_flights): - raise ValueError( - "{} service providers were specified, but data for only {} test flights were provided".format( - len(service_providers), len(test_flights) - ) - ) - for i, target in enumerate(service_providers): - p = CreateTestParameters(requested_flights=[test_flights[i]]) - check = test_scenario.check("Successful injection", [target.participant_id]) - try: - query = target.submit_test(p, test_id) - except RequestException as e: - stacktrace = "".join( - traceback.format_exception(type(e), value=e, tb=e.__traceback__) - ) - check.record_failed( - summary="Error while trying to inject test flight", - severity=Severity.High, - details=f"While trying to inject a test flight into {target.participant_id}, encountered error:\n{stacktrace}", - ) - raise RuntimeError("High-severity issue did not abort test scenario") - test_scenario.record_query(query) - try: - if query.status_code != 200: - raise ValueError( - f"Expected response code 200 but received {query.status_code} instead" - ) - if "json" not in query.response: - raise ValueError("Response did not contain a JSON body") - changed_test: ChangeTestResponse = ImplicitDict.parse( - query.response.json, ChangeTestResponse - ) - injected_tests.append( - InjectedTest( - participant_id=target.participant_id, - test_id=test_id, - version=changed_test.version, - ) - ) - injections = changed_test.injected_flights - check.record_passed() - except ValueError as e: - check.record_failed( - summary="Error injecting test flight", - severity=Severity.High, - details=f"Attempting to inject a test flight into {target.participant_id}, encountered status code {query.status_code}: {str(e)}", - query_timestamps=[query.request.timestamp], - ) - raise RuntimeError("High-severity issue did not abort test scenario") - - start_time = None - end_time = None - for flight in injections: - injected_flights.append( - InjectedFlight( - uss_participant_id=target.participant_id, - test_id=test_id, - flight=TestFlight(flight), - query_timestamp=query.request.timestamp, - ) - ) - earliest_time = min(t.timestamp.datetime for t in flight.telemetry) - latest_time = max(t.timestamp.datetime for t in flight.telemetry) - if start_time is None or earliest_time < start_time: - start_time = earliest_time - if end_time is None or latest_time > end_time: - end_time = latest_time - now = arrow.utcnow().datetime - dt0 = (start_time - now).total_seconds() - dt1 = (end_time - now).total_seconds() - test_scenario.record_note( - f"{test_id} time range", - f"Injected flights start {dt0:.1f} seconds from now and end {dt1:.1f} seconds from now", - ) - - # Make sure the injected flights can be identified correctly by the test harness - with test_scenario.check("Identifiable flights") as check: - errors = display_data_evaluator.injected_flights_errors(injected_flights) - if errors: - check.record_failed( - "Injected flights not suitable for test", - Severity.High, - details="When checking the suitability of the flights (as injected) for the test, found:\n" - + "\n".join(errors), - query_timestamps=[f.query_timestamp for f in injected_flights], - ) - raise RuntimeError("High-severity issue did not abort test scenario") - - config = evaluation_configuration.configuration - test_scenario._virtual_observer = VirtualObserver( - injected_flights=InjectedFlightCollection(injected_flights), - repeat_query_rect_period=config.repeat_query_rect_period, - min_query_diagonal_m=config.min_query_diagonal, - relevant_past_data_period=realtime_period - + config.max_propagation_latency.timedelta, - ) - return injected_flights, injected_tests 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 e371b0fd48..956da71fda 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/display_data_evaluator.py @@ -6,11 +6,12 @@ import math import s2sphere from s2sphere import LatLng, LatLngRect + from monitoring.uss_qualifier.scenarios.astm.netrid.common_dictionary_evaluator import ( RIDCommonDictionaryEvaluator, ) -from monitoring.monitorlib.fetch import Query, QueryType +from monitoring.monitorlib.fetch import Query from monitoring.monitorlib.fetch.rid import ( all_flights, FetchedFlights, @@ -18,7 +19,6 @@ Position, ) from monitoring.uss_qualifier.resources.astm.f3411.dss import DSSInstance -from uas_standards.interuss.automated_testing.rid.v1.injection import RIDAircraftState from uas_standards.interuss.automated_testing.rid.v1.observation import ( Flight, GetDisplayDataResponse, @@ -36,15 +36,9 @@ from monitoring.uss_qualifier.scenarios.astm.netrid.virtual_observer import ( VirtualObserver, ) -from monitoring.uss_qualifier.scenarios.scenario import ( - TestScenarioType, - TestScenario, -) +from monitoring.uss_qualifier.scenarios.scenario import TestScenario from monitoring.uss_qualifier.scenarios.astm.netrid.injection import InjectedFlight -DISTANCE_TOLERANCE_M = 0.01 -COORD_TOLERANCE_DEG = 360 / geo.EARTH_CIRCUMFERENCE_M * DISTANCE_TOLERANCE_M - def _rect_str(rect) -> str: return "({}, {})-({}, {})".format( @@ -55,41 +49,6 @@ def _rect_str(rect) -> str: ) -def _telemetry_match(t1: RIDAircraftState, t2: RIDAircraftState) -> bool: - """Determine whether two telemetry points may be mistaken for each other.""" - return ( - abs(t1.position.lat - t2.position.lat) < COORD_TOLERANCE_DEG - and abs(t1.position.lng - t2.position.lng) < COORD_TOLERANCE_DEG - ) - - -def injected_flights_errors(injected_flights: List[InjectedFlight]) -> List[str]: - """Determine whether each telemetry in each injected flight can be easily distinguished from each other. - - Args: - injected_flights: Full set of flights injected into Service Providers. - - Returns: List of error messages, or an empty list if no errors. - """ - errors: List[str] = [] - for f1, injected_flight in enumerate(injected_flights): - for t1, injected_telemetry in enumerate(injected_flight.flight.telemetry): - for t2, other_telemetry in enumerate( - injected_flight.flight.telemetry[t1 + 1 :] - ): - if _telemetry_match(injected_telemetry, other_telemetry): - errors.append( - f"{injected_flight.uss_participant_id}'s flight with injection ID {injected_flight.flight.injection_id} in test {injected_flight.test_id} has telemetry at indices {t1} and {t1 + 1 + t2} which can be mistaken for each other; (lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}) and (lat={other_telemetry.position.lat}, lng={other_telemetry.position.lng}) respectively" - ) - for f2, other_flight in enumerate(injected_flights[f1 + 1 :]): - for t2, other_telemetry in enumerate(other_flight.flight.telemetry): - if _telemetry_match(injected_telemetry, other_telemetry): - errors.append( - f"{injected_flight.uss_participant_id}'s flight with injection ID {injected_flight.flight.injection_id} in test {injected_flight.test_id} has telemetry at index {t1} that can be mistaken for telemetry index {t2} in {other_flight.uss_participant_id}'s flight with injection ID {other_flight.flight.injection_id} in test {other_flight.test_id}; (lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}) and (lat={other_telemetry.position.lat}, lng={other_telemetry.position.lng}) respectively" - ) - return errors - - @dataclass class DPObservedFlight(object): query: FetchedUSSFlights @@ -114,7 +73,7 @@ class TelemetryMapping(object): observed_flight: ObservationType -def _make_flight_mapping( +def map_observations_to_injected_flights( injected_flights: List[InjectedFlight], observed_flights: List[ObservationType], ) -> Dict[str, TelemetryMapping]: @@ -128,7 +87,7 @@ def _make_flight_mapping( injected_flights: Flights injected into RID Service Providers under test. observed_flights: Flight observed from an RID Display Provider under test. - Returns: Mapping betweenInjectedFlight and observed Flight, indexed by injection_id. + Returns: Mapping between InjectedFlight and observed Flight, indexed by injection_id. """ mapping: Dict[str, TelemetryMapping] = {} for injected_flight in injected_flights: @@ -154,7 +113,7 @@ def _make_flight_mapping( for t1, injected_telemetry in enumerate(injected_flight.flight.telemetry): dlat = abs(p.lat - injected_telemetry.position.lat) dlng = abs(p.lng - injected_telemetry.position.lng) - if dlat < COORD_TOLERANCE_DEG and dlng < COORD_TOLERANCE_DEG: + if dlat < geo.COORD_TOLERANCE_DEG and dlng < geo.COORD_TOLERANCE_DEG: new_distance = math.sqrt(math.pow(dlat, 2) + math.pow(dlng, 2)) if new_distance < smallest_distance: best_match = TelemetryMapping( @@ -181,6 +140,38 @@ def _make_flight_mapping( return mapping +def map_fetched_to_injected_flights( + injected_flights: List[InjectedFlight], + fetched_flights: List[FetchedUSSFlights], +) -> Dict[str, TelemetryMapping]: + """Identify which of the fetched flights (if any) matches to each of the injected flights. + + See `map_observations_to_injected_flights`. + If it is not already set, sets the observation flight's server ID to the one of the matching injected flight. + + :param injected_flights: Flights injected into RID Service Providers under test. + :param fetched_flights: Flight observed from an RID Display Provider under test. + :return: Mapping between InjectedFlight and observed Flight, indexed by injection_id. + """ + 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)) + + tel_mapping = map_observations_to_injected_flights( + injected_flights, observed_flights + ) + + # TODO: a better approach here would be to separately map flights URL to participant IDs based on all TelemetryMapping encountered, and set retroactively the participant ID on all queries + for mapping in tel_mapping.values(): + if mapping.observed_flight.query.participant_id is None: + mapping.observed_flight.query.set_participant_id( + mapping.injected_flight.uss_participant_id + ) + + return tel_mapping + + class RIDObservationEvaluator(object): """Evaluates observations of an RID system over time. @@ -239,12 +230,18 @@ def evaluate_system_instantaneously( get_details=True, rid_version=self._rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + dss_participant_id=self._dss.participant_id, + ) + + # map observed flights to injected flight and attribute participant ID + mapping_by_injection_id = map_fetched_to_injected_flights( + self._injected_flights, list(sp_observation.uss_flight_queries.values()) ) for q in sp_observation.queries: self._test_scenario.record_query(q) - self._evaluate_sp_observation(sp_observation, rect) + # Evaluate observations + self._evaluate_sp_observation(rect, sp_observation, mapping_by_injection_id) step_report = self._test_scenario.end_test_step() perform_observation = step_report.successful() @@ -341,7 +338,7 @@ def _evaluate_normal_observation( query_timestamps=[query.request.timestamp], ) - mapping_by_injection_id = _make_flight_mapping( + mapping_by_injection_id = map_observations_to_injected_flights( self._injected_flights, observation.flights ) @@ -381,7 +378,7 @@ def _evaluate_normal_observation( ) as check: if ( abs(observed_position.alt - injected_position.alt) - > DISTANCE_TOLERANCE_M + > geo.DISTANCE_TOLERANCE_M ): check.record_failed( "Observed altitude does not match injected altitude", @@ -782,7 +779,7 @@ def _evaluate_obfuscated_clusters_observation( * geo.EARTH_CIRCUMFERENCE_M / 360 ) - if distance <= DISTANCE_TOLERANCE_M: + if distance <= geo.DISTANCE_TOLERANCE_M: # Flight was not obfuscated check.record_failed( summary="Error while evaluating obfuscation of individual flights. Flight was not obfuscated: it is at the center of the cluster.", @@ -815,8 +812,9 @@ def _evaluate_obfuscated_clusters_observation( def _evaluate_sp_observation( self, + requested_area: s2sphere.LatLngRect, sp_observation: FetchedFlights, - rect: s2sphere.LatLngRect, + mappings: Dict[str, TelemetryMapping], ) -> None: # Note: This step currently uses the DSS endpoint to perform a one-time query for ISAs, but this # endpoint is not strictly required. The PUT Subscription endpoint, followed immediately by the @@ -839,31 +837,18 @@ def _evaluate_sp_observation( ) return - observed_flights = [] - for uss_query in sp_observation.uss_flight_queries.values(): - for f in range(len(uss_query.flights)): - observed_flights.append(DPObservedFlight(query=uss_query, flight=f)) - mapping_by_injection_id = _make_flight_mapping( - self._injected_flights, observed_flights - ) - - for telemetry_mapping in mapping_by_injection_id.values(): - # For flights that were mapped to an injection ID, - # update the observation queries with the participant id for future use in the aggregate checks - telemetry_mapping.observed_flight.query.set_server_id( - telemetry_mapping.injected_flight.uss_participant_id - ) - diagonal_km = ( - rect.lo().get_distance(rect.hi()).degrees * geo.EARTH_CIRCUMFERENCE_KM / 360 + requested_area.lo().get_distance(requested_area.hi()).degrees + * geo.EARTH_CIRCUMFERENCE_KM + / 360 ) if diagonal_km > self._rid_version.max_diagonal_km: self._evaluate_area_too_large_sp_observation( - mapping_by_injection_id, rect, diagonal_km + mappings, requested_area, diagonal_km ) else: self._evaluate_normal_sp_observation( - rect, sp_observation, mapping_by_injection_id + requested_area, sp_observation, mappings ) def _evaluate_normal_sp_observation( @@ -932,7 +917,7 @@ def _evaluate_normal_sp_observation( ) as check: if ( abs(observed_position.alt - injected_position.alt) - > DISTANCE_TOLERANCE_M + > geo.DISTANCE_TOLERANCE_M ): check.record_failed( "Altitude reported by Service Provider does not match injected altitude", diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/dss_wrapper.py b/monitoring/uss_qualifier/scenarios/astm/netrid/dss_wrapper.py index 6c5dd91570..e49500a326 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/dss_wrapper.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/dss_wrapper.py @@ -126,7 +126,7 @@ def search_isas( end_time=end_time, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( main_check, @@ -176,7 +176,7 @@ def search_isas_expect_response_code( end_time=end_time, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -206,7 +206,7 @@ def get_isa( isa_id=isa_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result(check, isa, f"Failed to get ISA {isa_id}") @@ -245,7 +245,7 @@ def get_isa_expect_response_code( isa_id=isa_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -282,7 +282,7 @@ def put_isa_expect_response_code( isa_version=isa_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -326,7 +326,7 @@ def put_isa( isa_version=isa_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( main_check, mutated_isa.dss_query, f"Failed to insert ISA {isa_id}" @@ -457,7 +457,7 @@ def del_isa( isa_version=isa_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( main_check, del_isa.dss_query, f"Failed to delete ISA {isa_id}" @@ -542,7 +542,7 @@ def del_isa_expect_response_code( isa_version=isa_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -570,7 +570,7 @@ def cleanup_isa( isa_id=isa_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -585,7 +585,7 @@ def cleanup_isa( isa_version=isa.isa.version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -620,7 +620,7 @@ def search_subs( area=area, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -651,7 +651,7 @@ def get_sub( subscription_id=sub_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -691,7 +691,7 @@ def no_sub( subscription_id=sub_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -734,7 +734,7 @@ def put_sub_expect_response_code( subscription_version=sub_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -783,7 +783,7 @@ def put_sub( subscription_version=sub_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -815,7 +815,7 @@ def del_sub( subscription_version=sub_version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -854,7 +854,7 @@ def cleanup_sub( subscription_id=sub_id, rid_version=self._dss.rid_version, session=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( @@ -873,7 +873,7 @@ def cleanup_sub( subscription_version=sub.subscription.version, rid_version=self._dss.rid_version, utm_client=self._dss.client, - server_id=self._dss.participant_id, + participant_id=self._dss.participant_id, ) self._handle_query_result( diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/injection.py b/monitoring/uss_qualifier/scenarios/astm/netrid/injection.py index 618613b581..96452d4c26 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/injection.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/injection.py @@ -1,8 +1,22 @@ +import uuid from datetime import datetime +from typing import List, Tuple +import arrow from implicitdict import ImplicitDict +from uas_standards.interuss.automated_testing.rid.v1.injection import ChangeTestResponse -from monitoring.monitorlib.rid_automated_testing.injection_api import TestFlight +from monitoring.monitorlib import geo +from monitoring.monitorlib.rid_automated_testing.injection_api import ( + TestFlight, + CreateTestParameters, +) +from monitoring.uss_qualifier.common_data_definitions import Severity +from monitoring.uss_qualifier.resources.netrid import ( + FlightDataResource, + NetRIDServiceProviders, +) +from monitoring.uss_qualifier.scenarios.scenario import TestScenario class InjectedFlight(ImplicitDict): @@ -16,3 +30,125 @@ class InjectedTest(ImplicitDict): participant_id: str test_id: str version: str + + +def inject_flights( + test_scenario: TestScenario, + flights_data_res: FlightDataResource, + service_providers_res: NetRIDServiceProviders, +) -> Tuple[List[InjectedFlight], List[InjectedTest]]: + test_id = str(uuid.uuid4()) + test_flights = flights_data_res.get_test_flights() + service_providers = service_providers_res.service_providers + + injected_flights: List[InjectedFlight] = [] + injected_tests: List[InjectedTest] = [] + + if len(service_providers) > len(test_flights): + raise ValueError( + f"{len(service_providers)} service providers were specified, but data for only {len(test_flights)} test flights were provided" + ) + for i, target in enumerate(service_providers): + p = CreateTestParameters(requested_flights=[test_flights[i]]) + with test_scenario.check( + "Successful injection", [target.participant_id] + ) as check: + query = target.submit_test(p, test_id) + test_scenario.record_query(query) + + if query.status_code != 200: + check.record_failed( + summary="Error while trying to inject test flight", + severity=Severity.High, + details=f"Expected response code 200 from {target.participant_id} but received {query.status_code} while trying to inject a test flight", + query_timestamps=[query.request.timestamp], + ) + + if "json" not in query.response or query.response.json is None: + check.record_failed( + summary="Response to test flight injection request did not contain a JSON body", + severity=Severity.High, + details=f"Expected a JSON body in response to flight injection request", + query_timestamps=[query.request.timestamp], + ) + + changed_test: ChangeTestResponse = ImplicitDict.parse( + query.response.json, ChangeTestResponse + ) + injected_tests.append( + InjectedTest( + participant_id=target.participant_id, + test_id=test_id, + version=changed_test.version, + ) + ) + + start_time = None + end_time = None + for flight in changed_test.injected_flights: + injected_flights.append( + InjectedFlight( + uss_participant_id=target.participant_id, + test_id=test_id, + flight=TestFlight(flight), + query_timestamp=query.request.timestamp, + ) + ) + earliest_time = min(t.timestamp.datetime for t in flight.telemetry) + latest_time = max(t.timestamp.datetime for t in flight.telemetry) + if start_time is None or earliest_time < start_time: + start_time = earliest_time + if end_time is None or latest_time > end_time: + end_time = latest_time + now = arrow.utcnow().datetime + dt0 = (start_time - now).total_seconds() + dt1 = (end_time - now).total_seconds() + test_scenario.record_note( + f"{test_id} time range", + f"Injected flights start {dt0:.1f} seconds from now and end {dt1:.1f} seconds from now", + ) + + # Make sure the injected flights can be identified correctly by the test harness + with test_scenario.check("Identifiable flights") as check: + errors = injected_flights_errors(injected_flights) + if errors: + check.record_failed( + summary="Injected flights not suitable for test", + severity=Severity.High, + details="When checking the suitability of the flights (as injected) for the test, found:\n" + + "\n".join(errors), + query_timestamps=[f.query_timestamp for f in injected_flights], + ) + + return injected_flights, injected_tests + + +def injected_flights_errors(injected_flights: List[InjectedFlight]) -> List[str]: + """Determine whether each telemetry in each injected flight can be easily distinguished from each other. + + Args: + injected_flights: Full set of flights injected into Service Providers. + + Returns: List of error messages, or an empty list if no errors. + """ + errors: List[str] = [] + for f1, injected_flight in enumerate(injected_flights): + for t1, injected_telemetry in enumerate(injected_flight.flight.telemetry): + for t2, other_telemetry in enumerate( + injected_flight.flight.telemetry[t1 + 1 :] + ): + if geo.LatLngPoint.from_f3411(injected_telemetry.position).match( + geo.LatLngPoint.from_f3411(other_telemetry.position) + ): + errors.append( + f"{injected_flight.uss_participant_id}'s flight with injection ID {injected_flight.flight.injection_id} in test {injected_flight.test_id} has telemetry at indices {t1} and {t1 + 1 + t2} which can be mistaken for each other; (lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}) and (lat={other_telemetry.position.lat}, lng={other_telemetry.position.lng}) respectively" + ) + for f2, other_flight in enumerate(injected_flights[f1 + 1 :]): + for t2, other_telemetry in enumerate(other_flight.flight.telemetry): + if geo.LatLngPoint.from_f3411(injected_telemetry.position).match( + geo.LatLngPoint.from_f3411(other_telemetry.position) + ): + errors.append( + f"{injected_flight.uss_participant_id}'s flight with injection ID {injected_flight.flight.injection_id} in test {injected_flight.test_id} has telemetry at index {t1} that can be mistaken for telemetry index {t2} in {other_flight.uss_participant_id}'s flight with injection ID {other_flight.flight.injection_id} in test {other_flight.test_id}; (lat={injected_telemetry.position.lat}, lng={injected_telemetry.position.lng}) and (lat={other_telemetry.position.lat}, lng={other_telemetry.position.lng}) respectively" + ) + return errors diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/misbehavior.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/misbehavior.md index 0602647f31..af43f8b57f 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v19/misbehavior.md +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v19/misbehavior.md @@ -44,11 +44,11 @@ This particular test requires each flight to be uniquely identifiable by its 2D In order to properly test whether the SP handles authentication correctly, this step will first attempt to do a request with the proper credentials to confirm that the requested data is indeed available to any authorized query. -It then repeats the exact same request while omitting the credentials, and expects this to fail. +It then repeats the exact same request with incorrect credentials, and expects this to fail. #### Missing credentials check -This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v19.NET0500](../../../../requirements/astm/f3411/v19.md)**, +This check ensures that all requests are properly authenticated, as required by **[astm.f3411.v19.NET0210](../../../../requirements/astm/f3411/v19.md)**, and that requests for existing flights that are executed with missing or incorrect credentials fail. ## Cleanup diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/misbehavior.md b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/misbehavior.md index 5089d9d23c..698084d61d 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/misbehavior.md +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/v22a/misbehavior.md @@ -44,7 +44,7 @@ This particular test requires each flight to be uniquely identifiable by its 2D In order to properly test whether the SP handles authentication correctly, this step will first attempt to do a request with the proper credentials to confirm that the requested data is indeed available to any authorized query. -It then repeats the exact same request while omitting the credentials, and expects this to fail. +It then repeats the exact same request with incorrect credentials, and expects this to fail. #### Missing credentials check diff --git a/monitoring/uss_qualifier/scenarios/astm/netrid/virtual_observer.py b/monitoring/uss_qualifier/scenarios/astm/netrid/virtual_observer.py index fad4ca7759..4c7033cf21 100644 --- a/monitoring/uss_qualifier/scenarios/astm/netrid/virtual_observer.py +++ b/monitoring/uss_qualifier/scenarios/astm/netrid/virtual_observer.py @@ -1,5 +1,7 @@ +import time from datetime import timedelta, datetime -from typing import Optional +from typing import Optional, Callable, List +from loguru import logger import arrow from s2sphere import LatLngRect @@ -69,3 +71,50 @@ def get_last_time_of_interest(self) -> datetime: self._injected_flights.get_end_of_injected_data() + self._relevant_past_data_period ) + + def start_polling( + self, + interval: timedelta, + diagonals_m: List[float], + poll_fct: Callable[[LatLngRect], bool], + ) -> None: + """ + Start polling of the RID system. + + :param interval: polling interval. + :param diagonals_m: list of the query rectangle diagonals (in meters). + :param poll_fct: polling function to invoke. If it returns True, the polling will be immediately interrupted before the end. + """ + t_end = self.get_last_time_of_interest() + t_now = arrow.utcnow() + if t_now > t_end: + raise ValueError( + f"Cannot poll RID system: instructed to poll until {t_end}, which is before now ({t_now})" + ) + + logger.info(f"Polling from {t_now} until {t_end} every {interval}") + t_next = arrow.utcnow() + while arrow.utcnow() < t_end: + interrupt_polling = False + for diagonal_m in diagonals_m: + rect = self.get_query_rect(diagonal_m) + interrupt_polling = poll_fct(rect) + if interrupt_polling: + break + + if interrupt_polling: + logger.info(f"Polling ended early at {arrow.utcnow()}.") + break + + # Wait until minimum polling interval elapses + while t_next < arrow.utcnow(): + t_next += interval + if t_next > t_end: + logger.info(f"Polling ended normally at {t_end}.") + break + delay = t_next - arrow.utcnow() + if delay.total_seconds() > 0: + logger.debug( + f"Waiting {delay.total_seconds()} seconds before polling RID system again..." + ) + time.sleep(delay.total_seconds()) diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md b/monitoring/uss_qualifier/suites/astm/netrid/f3411_19.md index 464bbd5f6f..347a1f1add 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
DSS0030,a Implemented ASTM F3411-19 NetRID DSS interoperability
ASTM NetRID DSS: Simple ISA @@ -206,6 +206,11 @@ TODO ASTM NetRID: Operator interactions + + NET0210 + Implemented + ASTM NetRID SP clients misbehavior handling + NET0220 Implemented diff --git a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.yaml b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.yaml index db4afe785f..d2438492d8 100644 --- a/monitoring/uss_qualifier/suites/astm/utm/f3548_21.yaml +++ b/monitoring/uss_qualifier/suites/astm/utm/f3548_21.yaml @@ -72,20 +72,20 @@ actions: generator_type: action_generators.flight_planning.FlightPlannerCombinations resources: flight_planners: flight_planners - priority_planning_selector: priority_planning_selector? - priority_preemption_flights: priority_preemption_flights + nominal_planning_selector: nominal_planning_selector? + conflicting_flights: conflicting_flights dss: dss specification: action_to_repeat: test_scenario: scenario_type: scenarios.astm.utm.ConflictEqualPriorityNotPermitted resources: - flight_intents: priority_preemption_flights + flight_intents: conflicting_flights tested_uss: uss1 control_uss: uss2 dss: dss on_failure: Continue - combination_selector_source: priority_planning_selector + combination_selector_source: nominal_planning_selector flight_planners_source: flight_planners roles: - uss1 diff --git a/monitoring/uss_qualifier/suites/faa/uft/design/README.md b/monitoring/uss_qualifier/suites/faa/uft/design/README.md index 1b96404e88..887d5bb242 100644 --- a/monitoring/uss_qualifier/suites/faa/uft/design/README.md +++ b/monitoring/uss_qualifier/suites/faa/uft/design/README.md @@ -25,7 +25,7 @@ Note - As different USSes have different implementations, it could happen that y ## Steps to run the test -1. Set your uss_qualifier Interface implementation url in the [configuration file ](../../../../configurations/dev/faa/uft/local_message_signing.yaml) to run +1. Set your uss_qualifier Interface implementation url in the [configuration file ](../../../../configurations/dev/message_signing.yaml) to run the UFT message signing tests. If personal changes are needed, copy this yaml file to a personal configuration file in the [personal configuration folder](../../../../configurations/personal), and edit this file instead. The property to set is `resources.resource_declarations.flight_planners.specification.flight_planners.participant_id` @@ -48,17 +48,17 @@ The property to set is `resources.resource_declarations.flight_planners.specific ## Results SCD tests report is generated under [uss_qualifier](../../../../../../monitoring/uss_qualifier). -The message signing results will be in the report created for the overall run - report.json. Failed message signing checks will show up as `FailedChecks` within the `FinalizeMessageSigningReport` test scenario. +The message signing results will be in the report created for the overall run - report.json. Failed message signing checks will show up as `FailedChecks` within the `FinalizeMessageSigningReport` test scenario. ### Positive tests - A set of private/public keys are provided for use by mock_uss in message -signing analysis under the [build/test-certs/message-signing] folder. -This key pair, mock_faa_priv.pem/mock_faa_pub.der, is used by mock_uss -(when requested from an instance with the capability enabled) to sign its responses, and by `AuthAdapter` to sign requests of outgoing messages. +signing analysis under the [build/test-certs/message-signing] folder. +This key pair, mock_faa_priv.pem/mock_faa_pub.der, is used by mock_uss +(when requested from an instance with the capability enabled) to sign its responses, and by `AuthAdapter` to sign requests of outgoing messages. When the message signing mock_uss capability is enabled, the public key is served under the mock_uss endpoint - /mock/msgsigning/.well-known/uas-traffic-management/pub.der, - and can be retrieved by the USS under test in order for it to validate the - mock_uss responses, per UFT message signing requirements. This public key was provided by the FAA + /mock/msgsigning/.well-known/uas-traffic-management/pub.der, + and can be retrieved by the USS under test in order for it to validate the + mock_uss responses, per UFT message signing requirements. This public key was provided by the FAA and will pass SCVP validation for the UFT activity. A USS should pass all the uss_qualifier tests in this suite. No failed checks indicate the USS-under-test message-signed all its requests and responses. @@ -85,4 +85,4 @@ Below are examples of valid http message signature headers. Malformed headers ca "x-utm-message-signature": "utm-message-signature=:VrUhTe7g2PdnrX37t4hM6Dj7ggSy9YSYt6AqxvICSBTo+AFTVnhCw6k4Kpo1udVboepVYzYC4MHdjaGoTQ6hDT4gvH63QB3JyEqjs0TrAxFj78D5Rau7Sysku18Y/MJG1/cta7DRekdBQJnhFks0aIYzPTizYt0tUL9jx3yybyuK7jTNdtsFmN5qQDs2upTe0ivQjOWggGACMF1yxMZBsGmPLs24E5LssAfSpa1qunnWQNukMHYxtJ+GFMhAV4LDLsO3QQRidKhuhndqittYrGGujQwSz6WSaO8D+4DjR8vpWeR14JnwEIoS2oS6DiyX4fHMB296ai/tkbzklkbe5g==:" } } -``` \ No newline at end of file +``` diff --git a/monitoring/uss_qualifier/suites/suite.py b/monitoring/uss_qualifier/suites/suite.py index 0d9b7094dd..79cedd14d9 100644 --- a/monitoring/uss_qualifier/suites/suite.py +++ b/monitoring/uss_qualifier/suites/suite.py @@ -3,7 +3,7 @@ import os from datetime import datetime import json -from typing import Dict, List, Optional +from typing import Dict, List, Optional, Union, Callable, Iterator import arrow @@ -145,15 +145,9 @@ def _run_action_generator(self) -> ActionGeneratorReport: generator_type=self.action_generator.definition.generator_type, start_time=StringBasedDateTime(arrow.utcnow()), ) - while True: - action_report = self.action_generator.run_next_action() - if action_report is None: - break - report.actions.append(action_report) - if action_report.has_critical_problem(): - break - report.end_time = StringBasedDateTime(arrow.utcnow()) - report.successful = all(a.successful() for a in report.actions) + + _run_actions(self.action_generator.actions(), report) + return report @@ -218,6 +212,9 @@ def __init__( TestSuiteAction(action=action_dec, resources=self.local_resources) ) except MissingResourceError as e: + logger.warning( + f"Skipping action {a} ({action_dec.get_action_type()} {action_dec.get_child_type()}) because {str(e)}" + ) skipped_actions.append( SkippedActionReport( timestamp=StringBasedDateTime(arrow.utcnow().datetime), @@ -264,34 +261,15 @@ def run(self) -> TestSuiteReport: skipped_actions=self.skipped_actions, capability_evaluations=[], ) - success = True - for a in range(len(self.actions) + 1): - if a == len(self.actions): - # Execute report evaluation scenario as last action if specified, otherwise break loop - if self.definition.has_field_with_value("report_evaluation_scenario"): - action = self._make_report_evaluation_action(report) - else: - break - else: - action = self.actions[a] - action_report = action.run() - report.actions.append(action_report) - if action_report.has_critical_problem(): - success = False - break - if not action_report.successful(): - success = False - if action.declaration.on_failure == ReactionToFailure.Abort: - break - elif action.declaration.on_failure == ReactionToFailure.Continue: - continue - else: - raise ValueError( - f"Action {a} of test suite {self.definition.name} indicate an unrecognized reaction to failure: {str(action.declaration.on_failure)}" - ) - report.successful = success - report.end_time = StringBasedDateTime(datetime.utcnow()) + def actions() -> Iterator[TestSuiteAction]: + for a in self.actions: + yield a + # Execute report evaluation scenario as last action if specified, otherwise break loop + if self.definition.has_field_with_value("report_evaluation_scenario"): + yield self._make_report_evaluation_action(report) + + _run_actions(actions(), report) # Evaluate participants' capabilities if ( @@ -322,3 +300,28 @@ def run(self) -> TestSuiteReport: ) return report + + +def _run_actions( + actions: Iterator[TestSuiteAction], + report: Union[TestSuiteReport, ActionGeneratorReport], +) -> None: + success = True + for a, action in enumerate(actions): + action_report = action.run() + report.actions.append(action_report) + if action_report.has_critical_problem(): + success = False + break + if not action_report.successful(): + success = False + if action.declaration.on_failure == ReactionToFailure.Abort: + break + elif action.declaration.on_failure == ReactionToFailure.Continue: + continue + else: + raise ValueError( + f"Action {a} indicated an unrecognized reaction to failure: {str(action.declaration.on_failure)}" + ) + report.successful = success + report.end_time = StringBasedDateTime(datetime.utcnow()) diff --git a/monitoring/uss_qualifier/test_data/che/flight_intents/conflicting_flights.json b/monitoring/uss_qualifier/test_data/che/flight_intents/conflicting_flights.json index 59b6248886..dbeb97d9a1 100644 --- a/monitoring/uss_qualifier/test_data/che/flight_intents/conflicting_flights.json +++ b/monitoring/uss_qualifier/test_data/che/flight_intents/conflicting_flights.json @@ -1,6 +1,6 @@ { "intents": { - "first_flight": { + "flight_1_planned_vol_A": { "full": { "reference_time": "2023-02-12T10:34:14.483425+00:00", "request": { @@ -225,14 +225,6 @@ { "lng": 7.477601673804613, "lat": 46.974785690027296 - }, - { - "lng": 7.477582533186026, - "lat": 46.974787633340085 - }, - { - "lng": 7.477563763022608, - "lat": 46.97479085141769 } ] }, @@ -273,7 +265,7 @@ "cellular" ], "endurance_minutes": 30, - "emergency_procedure_url": "https://example.uav.com/emergency", + "emergency_procedure_url": "https://example.interussplatform.org/emergency", "operator_id": "CHEo5kut30e0mt01-qwe", "uas_id": "", "uas_type_certificate": "" @@ -281,9 +273,41 @@ } } }, - "first_flight_activated": { + "flight_1_activated_vol_A": { + "delta": { + "source": "flight_1_planned_vol_A", + "mutation": { + "request": { + "operational_intent": { + "state": "Activated" + } + } + } + } + }, + "flight_1_planned_vol_A_extended": { + "delta": { + "source": "flight_1_planned_vol_A", + "mutation": { + "request": { + "operational_intent": { + "volumes": [ + { + "volume": { + "altitude_lower": { + "value": 575.0 + } + } + } + ] + } + } + } + } + }, + "flight_1_activated_vol_A_extended": { "delta": { - "source": "first_flight", + "source": "flight_1_planned_vol_A_extended", "mutation": { "request": { "operational_intent": { @@ -293,7 +317,42 @@ } } }, - "conflicting_flight": { + "flight_1_planned_vol_B": { + "delta": { + "source": "flight_1_planned_vol_A", + "mutation": { + "request": { + "operational_intent": { + "volumes": [ + { + "volume": { + "altitude_lower": { + "value": 650.0 + }, + "altitude_upper": { + "value": 705.0 + } + } + } + ] + } + } + } + } + }, + "flight_1_activated_vol_B": { + "delta": { + "source": "flight_1_planned_vol_B", + "mutation": { + "request": { + "operational_intent": { + "state": "Activated" + } + } + } + } + }, + "flight_2_planned_vol_A": { "full": { "reference_time": "2023-02-12T10:34:14.483425+00:00", "request": { @@ -592,7 +651,7 @@ ], "state": "Accepted", "off_nominal_volumes": [], - "priority": 0 + "priority": 100 }, "flight_authorisation": { "uas_serial_number": "1AF49UL5CC5J6K", @@ -606,13 +665,377 @@ "cellular" ], "endurance_minutes": 30, - "emergency_procedure_url": "https://example.uav.com/emergency", + "emergency_procedure_url": "https://example.interussplatform.org/emergency", "operator_id": "CHEo5kut30e0mt01-qwe", "uas_id": "", "uas_type_certificate": "" } } } + }, + "flight_2_activated_vol_A": { + "delta": { + "source": "flight_2_planned_vol_A", + "mutation": { + "request": { + "operational_intent": { + "state": "Activated" + } + } + } + } + }, + "flight_2_activated_vol_B": { + "delta": { + "source": "flight_2_activated_vol_A", + "mutation": { + "request": { + "operational_intent": { + "volumes": [ + { + "volume": { + "altitude_lower": { + "value": 650.0 + }, + "altitude_upper": { + "value": 705.0 + } + } + } + ] + } + } + } + } + }, + "flight_2_equal_prio_planned_vol_B": { + "delta": { + "source": "flight_2_activated_vol_B", + "mutation": { + "request": { + "operational_intent": { + "state": "Accepted", + "priority": 0 + } + } + } + } + }, + "flight_2_equal_prio_activated_vol_B": { + "delta": { + "source": "flight_2_equal_prio_planned_vol_B", + "mutation": { + "request": { + "operational_intent": { + "state": "Activated" + } + } + } + } + }, + "flight_2_equal_prio_nonconforming_vol_A": { + "delta": { + "source": "flight_2_equal_prio_activated_vol_B", + "mutation": { + "request": { + "operational_intent": { + "state": "Nonconforming", + "off_nominal_volumes": [ + { + "volume": { + "outline_polygon": { + "vertices": [ + { + "lng": 7.474315728091042, + "lat": 46.97716400145211 + }, + { + "lng": 7.474303247689658, + "lat": 46.97717412304557 + }, + { + "lng": 7.474292276891787, + "lat": 46.9771850331586 + }, + { + "lng": 7.474282921352688, + "lat": 46.97719662672131 + }, + { + "lng": 7.474275271172041, + "lat": 46.97720879208173 + }, + { + "lng": 7.474269400026217, + "lat": 46.97722141208117 + }, + { + "lng": 7.4742653644586845, + "lat": 46.977234365182404 + }, + { + "lng": 7.474263203335437, + "lat": 46.97724752664021 + }, + { + "lng": 7.474262937470636, + "lat": 46.97726076970267 + }, + { + "lng": 7.474264569426098, + "lat": 46.97727396683188 + }, + { + "lng": 7.47426808348659, + "lat": 46.97728699093222 + }, + { + "lng": 7.474273445811106, + "lat": 46.97729971657432 + }, + { + "lng": 7.474280604758724, + "lat": 46.97731202120303 + }, + { + "lng": 7.4742894913859015, + "lat": 46.97732378631779 + }, + { + "lng": 7.47430002011039, + "lat": 46.977334898613684 + }, + { + "lng": 7.474312089535409, + "lat": 46.97734525107282 + }, + { + "lng": 7.4743255834261335, + "lat": 46.97735474399491 + }, + { + "lng": 7.47434037182908, + "lat": 46.977363285957416 + }, + { + "lng": 7.474356312323634, + "lat": 46.97737079469613 + }, + { + "lng": 7.47437325139364, + "lat": 46.977377197897326 + }, + { + "lng": 7.474391025905868, + "lat": 46.97738243389426 + }, + { + "lng": 7.474409464681103, + "lat": 46.977386452261086 + }, + { + "lng": 7.474428390142731, + "lat": 46.97738921429845 + }, + { + "lng": 7.4744476200269405, + "lat": 46.97739069340619 + }, + { + "lng": 7.474466969138073, + "lat": 46.97739087533958 + }, + { + "lng": 7.474486251132214, + "lat": 46.97738975834647 + }, + { + "lng": 7.474505280311834, + "lat": 46.97738735318418 + }, + { + "lng": 7.47452387341421, + "lat": 46.97738368301589 + }, + { + "lng": 7.474541851376407, + "lat": 46.97737878318756 + }, + { + "lng": 7.474559041059788, + "lat": 46.97737270088755 + }, + { + "lng": 7.474575276917473, + "lat": 46.9773654946921 + }, + { + "lng": 7.474590402588685, + "lat": 46.977357234001225 + }, + { + "lng": 7.474604272404609, + "lat": 46.97734799837037 + }, + { + "lng": 7.4780602717187445, + "lat": 46.97480899404357 + }, + { + "lng": 7.478072750859629, + "lat": 46.97479887202181 + }, + { + "lng": 7.47808372039712, + "lat": 46.97478796152745 + }, + { + "lng": 7.478093074689058, + "lat": 46.97477636763495 + }, + { + "lng": 7.478100723649223, + "lat": 46.97476420200029 + }, + { + "lng": 7.478106593614889, + "lat": 46.974751581785505 + }, + { + "lng": 7.478110628056212, + "lat": 46.97473862853046 + }, + { + "lng": 7.4781127881205816, + "lat": 46.9747254669823 + }, + { + "lng": 7.478113053006759, + "lat": 46.97471222389403 + }, + { + "lng": 7.478111420165148, + "lat": 46.974699026803876 + }, + { + "lng": 7.478107905322289, + "lat": 46.97468600280696 + }, + { + "lng": 7.478102542329355, + "lat": 46.974673277331334 + }, + { + "lng": 7.478095382836098, + "lat": 46.97466097293006 + }, + { + "lng": 7.478086495793389, + "lat": 46.9746492081009 + }, + { + "lng": 7.478075966789133, + "lat": 46.97463809614524 + }, + { + "lng": 7.47806389722399, + "lat": 46.97462774407688 + }, + { + "lng": 7.478050403334804, + "lat": 46.97461825159139 + }, + { + "lng": 7.4780356150751714, + "lat": 46.97460971010614 + }, + { + "lng": 7.478019674863899, + "lat": 46.97460220187985 + }, + { + "lng": 7.478002736213457, + "lat": 46.97459579922035 + }, + { + "lng": 7.477984962251586, + "lat": 46.97459056378839 + }, + { + "lng": 7.477966524150307, + "lat": 46.974586546003664 + }, + { + "lng": 7.477947599477487, + "lat": 46.974583784559336 + }, + { + "lng": 7.477928370486799, + "lat": 46.97458230604945 + }, + { + "lng": 7.477909022362576, + "lat": 46.974582124712704 + }, + { + "lng": 7.4778897414364325, + "lat": 46.97458324229544 + }, + { + "lng": 7.47787071339284, + "lat": 46.974585648034825 + }, + { + "lng": 7.477852121480946, + "lat": 46.974589318762405 + }, + { + "lng": 7.477834144749823, + "lat": 46.974594219127326 + }, + { + "lng": 7.47781695632419, + "lat": 46.97460030193667 + }, + { + "lng": 7.477800721737151, + "lat": 46.97460750861006 + }, + { + "lng": 7.47778559733606, + "lat": 46.974615769743735 + }, + { + "lng": 7.477771728776835, + "lat": 46.97462500577891 + } + ] + }, + "altitude_lower": { + "value": 605.0, + "reference": "W84", + "units": "M" + }, + "altitude_upper": { + "value": 635.0, + "reference": "W84", + "units": "M" + } + }, + "time_start": { + "value": "2023-02-12T10:27:14.483425+00:00", + "format": "RFC3339" + }, + "time_end": { + "value": "2023-02-12T10:52:14.483425+00:00", + "format": "RFC3339" + } + } + ] + } + } + } + } } } } diff --git a/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_auths.json b/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_auths.json index daa0f3d57a..2a72a323d3 100644 --- a/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_auths.json +++ b/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_auths.json @@ -61,7 +61,7 @@ "cellular" ], "endurance_minutes": 30, - "emergency_procedure_url": "https://uav.example.com/emergency", + "emergency_procedure_url": "https://example.interussplatform.org/emergency", "operator_id": "CHEo5kut30e0mt01-qwe" } } @@ -128,7 +128,7 @@ "cellular" ], "endurance_minutes": 30, - "emergency_procedure_url": "https://uav.example.com/emergency", + "emergency_procedure_url": "https://example.interussplatform.org/emergency", "operator_id": "CHEo5kut30e0mt01-qwe" } } diff --git a/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_intents.yaml b/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_intents.yaml index c8c624d89f..31d2e98e7e 100644 --- a/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_intents.yaml +++ b/monitoring/uss_qualifier/test_data/che/flight_intents/invalid_flight_intents.yaml @@ -41,7 +41,7 @@ intents: connectivity_methods: - cellular endurance_minutes: 30 - emergency_procedure_url: https://uav.example.com/emergency + emergency_procedure_url: https://example.interussplatform.org/emergency operator_id: CHEo5kut30e0mt01-qwe valid_activated: diff --git a/monitoring/uss_qualifier/test_data/che/flight_intents/priority_preemption.json b/monitoring/uss_qualifier/test_data/che/flight_intents/priority_preemption.json deleted file mode 100644 index b7830c0b1b..0000000000 --- a/monitoring/uss_qualifier/test_data/che/flight_intents/priority_preemption.json +++ /dev/null @@ -1,1041 +0,0 @@ -{ - "intents": { - "flight_1_planned_vol_A": { - "full": { - "reference_time": "2023-02-12T10:34:14.483425+00:00", - "request": { - "operational_intent": { - "volumes": [ - { - "volume": { - "outline_polygon": { - "vertices": [ - { - "lng": 7.477423822749622, - "lat": 46.97491999984008 - }, - { - "lng": 7.477423821039847, - "lat": 46.97538499982026 - }, - { - "lng": 7.477424770457274, - "lat": 46.97539822817162 - }, - { - "lng": 7.477427609667229, - "lat": 46.975411329130466 - }, - { - "lng": 7.477432311328011, - "lat": 46.975424176527724 - }, - { - "lng": 7.477438830161459, - "lat": 46.97543664663613 - }, - { - "lng": 7.477447103388957, - "lat": 46.975448619361856 - }, - { - "lng": 7.477457051335981, - "lat": 46.975459979401066 - }, - { - "lng": 7.477468578199379, - "lat": 46.97547061735031 - }, - { - "lng": 7.477481572969964, - "lat": 46.97548043076024 - }, - { - "lng": 7.4774959105015855, - "lat": 46.97548932512221 - }, - { - "lng": 7.477511452716338, - "lat": 46.97549721477847 - }, - { - "lng": 7.47752804993433, - "lat": 46.97550402374711 - }, - { - "lng": 7.477545542315188, - "lat": 46.975509686453854 - }, - { - "lng": 7.477563761397435, - "lat": 46.97551414836356 - }, - { - "lng": 7.477582531720886, - "lat": 46.9755173665054 - }, - { - "lng": 7.477601672516463, - "lat": 46.975519309886806 - }, - { - "lng": 7.477620999447144, - "lat": 46.97551995979184 - }, - { - "lng": 7.478057000544437, - "lat": 46.97551995980457 - }, - { - "lng": 7.478076327475301, - "lat": 46.975519309900726 - }, - { - "lng": 7.478095468271412, - "lat": 46.97551736652059 - }, - { - "lng": 7.478114238595763, - "lat": 46.97551414838003 - }, - { - "lng": 7.478132457679282, - "lat": 46.97550968647161 - }, - { - "lng": 7.478149950061773, - "lat": 46.97550402376608 - }, - { - "lng": 7.478166547281737, - "lat": 46.97549721479852 - }, - { - "lng": 7.4781820894987705, - "lat": 46.97548932514323 - }, - { - "lng": 7.478196427032943, - "lat": 46.97548043078203 - }, - { - "lng": 7.478209421806301, - "lat": 46.97547061737267 - }, - { - "lng": 7.478220948672645, - "lat": 46.975459979423775 - }, - { - "lng": 7.478230896622737, - "lat": 46.97544861938469 - }, - { - "lng": 7.4782391698533655, - "lat": 46.97543664665883 - }, - { - "lng": 7.4782456886899595, - "lat": 46.975424176550064 - }, - { - "lng": 7.4782503903538515, - "lat": 46.97541132915219 - }, - { - "lng": 7.478253229566841, - "lat": 46.97539822819251 - }, - { - "lng": 7.478254178987183, - "lat": 46.975384999840095 - }, - { - "lng": 7.478254177277408, - "lat": 46.974919999820244 - }, - { - "lng": 7.478253227761765, - "lat": 46.97490677142331 - }, - { - "lng": 7.4782503884602685, - "lat": 46.97489367042681 - }, - { - "lng": 7.4782456867183855, - "lat": 46.97488082300081 - }, - { - "lng": 7.478239167817867, - "lat": 46.974868352873266 - }, - { - "lng": 7.478230894540598, - "lat": 46.974856380138455 - }, - { - "lng": 7.478220946563947, - "lat": 46.974845020100375 - }, - { - "lng": 7.478209419693374, - "lat": 46.974834382162385 - }, - { - "lng": 7.47819642493976, - "lat": 46.974824568773556 - }, - { - "lng": 7.4781820874502785, - "lat": 46.97481567444202 - }, - { - "lng": 7.478166545303149, - "lat": 46.97480778482489 - }, - { - "lng": 7.478149948177879, - "lat": 46.9748009759033 - }, - { - "lng": 7.4781324559137685, - "lat": 46.97479531325065 - }, - { - "lng": 7.478114236970597, - "lat": 46.97479085140123 - }, - { - "lng": 7.478095466806278, - "lat": 46.9747876333249 - }, - { - "lng": 7.478076326187155, - "lat": 46.97478569001336 - }, - { - "lng": 7.478056999447158, - "lat": 46.974785040181715 - }, - { - "lng": 7.477621000544429, - "lat": 46.97478504019445 - }, - { - "lng": 7.477601673804613, - "lat": 46.974785690027296 - } - ] - }, - "altitude_lower": { - "value": 605.0, - "reference": "W84", - "units": "M" - }, - "altitude_upper": { - "value": 635.0, - "reference": "W84", - "units": "M" - } - }, - "time_start": { - "value": "2023-02-12T10:27:14.483425+00:00", - "format": "RFC3339" - }, - "time_end": { - "value": "2023-02-12T10:52:14.483425+00:00", - "format": "RFC3339" - } - } - ], - "state": "Accepted", - "off_nominal_volumes": [], - "priority": 0 - }, - "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://uav.com/emergency", - "operator_id": "CHEo5kut30e0mt01-qwe", - "uas_id": "", - "uas_type_certificate": "" - } - } - } - }, - "flight_1_activated_vol_A": { - "delta": { - "source": "flight_1_planned_vol_A", - "mutation": { - "request": { - "operational_intent": { - "state": "Activated" - } - } - } - } - }, - "flight_1_planned_vol_A_extended": { - "delta": { - "source": "flight_1_planned_vol_A", - "mutation": { - "request": { - "operational_intent": { - "volumes": [ - { - "volume": { - "altitude_lower": { - "value": 575.0 - } - } - } - ] - } - } - } - } - }, - "flight_1_activated_vol_A_extended": { - "delta": { - "source": "flight_1_planned_vol_A_extended", - "mutation": { - "request": { - "operational_intent": { - "state": "Activated" - } - } - } - } - }, - "flight_1_planned_vol_B": { - "delta": { - "source": "flight_1_planned_vol_A", - "mutation": { - "request": { - "operational_intent": { - "volumes": [ - { - "volume": { - "altitude_lower": { - "value": 650.0 - }, - "altitude_upper": { - "value": 705.0 - } - } - } - ] - } - } - } - } - }, - "flight_1_activated_vol_B": { - "delta": { - "source": "flight_1_planned_vol_B", - "mutation": { - "request": { - "operational_intent": { - "state": "Activated" - } - } - } - } - }, - "flight_2_planned_vol_A": { - "full": { - "reference_time": "2023-02-12T10:34:14.483425+00:00", - "request": { - "operational_intent": { - "volumes": [ - { - "volume": { - "outline_polygon": { - "vertices": [ - { - "lng": 7.474315728091042, - "lat": 46.97716400145211 - }, - { - "lng": 7.474303247689658, - "lat": 46.97717412304557 - }, - { - "lng": 7.474292276891787, - "lat": 46.9771850331586 - }, - { - "lng": 7.474282921352688, - "lat": 46.97719662672131 - }, - { - "lng": 7.474275271172041, - "lat": 46.97720879208173 - }, - { - "lng": 7.474269400026217, - "lat": 46.97722141208117 - }, - { - "lng": 7.4742653644586845, - "lat": 46.977234365182404 - }, - { - "lng": 7.474263203335437, - "lat": 46.97724752664021 - }, - { - "lng": 7.474262937470636, - "lat": 46.97726076970267 - }, - { - "lng": 7.474264569426098, - "lat": 46.97727396683188 - }, - { - "lng": 7.47426808348659, - "lat": 46.97728699093222 - }, - { - "lng": 7.474273445811106, - "lat": 46.97729971657432 - }, - { - "lng": 7.474280604758724, - "lat": 46.97731202120303 - }, - { - "lng": 7.4742894913859015, - "lat": 46.97732378631779 - }, - { - "lng": 7.47430002011039, - "lat": 46.977334898613684 - }, - { - "lng": 7.474312089535409, - "lat": 46.97734525107282 - }, - { - "lng": 7.4743255834261335, - "lat": 46.97735474399491 - }, - { - "lng": 7.47434037182908, - "lat": 46.977363285957416 - }, - { - "lng": 7.474356312323634, - "lat": 46.97737079469613 - }, - { - "lng": 7.47437325139364, - "lat": 46.977377197897326 - }, - { - "lng": 7.474391025905868, - "lat": 46.97738243389426 - }, - { - "lng": 7.474409464681103, - "lat": 46.977386452261086 - }, - { - "lng": 7.474428390142731, - "lat": 46.97738921429845 - }, - { - "lng": 7.4744476200269405, - "lat": 46.97739069340619 - }, - { - "lng": 7.474466969138073, - "lat": 46.97739087533958 - }, - { - "lng": 7.474486251132214, - "lat": 46.97738975834647 - }, - { - "lng": 7.474505280311834, - "lat": 46.97738735318418 - }, - { - "lng": 7.47452387341421, - "lat": 46.97738368301589 - }, - { - "lng": 7.474541851376407, - "lat": 46.97737878318756 - }, - { - "lng": 7.474559041059788, - "lat": 46.97737270088755 - }, - { - "lng": 7.474575276917473, - "lat": 46.9773654946921 - }, - { - "lng": 7.474590402588685, - "lat": 46.977357234001225 - }, - { - "lng": 7.474604272404609, - "lat": 46.97734799837037 - }, - { - "lng": 7.4780602717187445, - "lat": 46.97480899404357 - }, - { - "lng": 7.478072750859629, - "lat": 46.97479887202181 - }, - { - "lng": 7.47808372039712, - "lat": 46.97478796152745 - }, - { - "lng": 7.478093074689058, - "lat": 46.97477636763495 - }, - { - "lng": 7.478100723649223, - "lat": 46.97476420200029 - }, - { - "lng": 7.478106593614889, - "lat": 46.974751581785505 - }, - { - "lng": 7.478110628056212, - "lat": 46.97473862853046 - }, - { - "lng": 7.4781127881205816, - "lat": 46.9747254669823 - }, - { - "lng": 7.478113053006759, - "lat": 46.97471222389403 - }, - { - "lng": 7.478111420165148, - "lat": 46.974699026803876 - }, - { - "lng": 7.478107905322289, - "lat": 46.97468600280696 - }, - { - "lng": 7.478102542329355, - "lat": 46.974673277331334 - }, - { - "lng": 7.478095382836098, - "lat": 46.97466097293006 - }, - { - "lng": 7.478086495793389, - "lat": 46.9746492081009 - }, - { - "lng": 7.478075966789133, - "lat": 46.97463809614524 - }, - { - "lng": 7.47806389722399, - "lat": 46.97462774407688 - }, - { - "lng": 7.478050403334804, - "lat": 46.97461825159139 - }, - { - "lng": 7.4780356150751714, - "lat": 46.97460971010614 - }, - { - "lng": 7.478019674863899, - "lat": 46.97460220187985 - }, - { - "lng": 7.478002736213457, - "lat": 46.97459579922035 - }, - { - "lng": 7.477984962251586, - "lat": 46.97459056378839 - }, - { - "lng": 7.477966524150307, - "lat": 46.974586546003664 - }, - { - "lng": 7.477947599477487, - "lat": 46.974583784559336 - }, - { - "lng": 7.477928370486799, - "lat": 46.97458230604945 - }, - { - "lng": 7.477909022362576, - "lat": 46.974582124712704 - }, - { - "lng": 7.4778897414364325, - "lat": 46.97458324229544 - }, - { - "lng": 7.47787071339284, - "lat": 46.974585648034825 - }, - { - "lng": 7.477852121480946, - "lat": 46.974589318762405 - }, - { - "lng": 7.477834144749823, - "lat": 46.974594219127326 - }, - { - "lng": 7.47781695632419, - "lat": 46.97460030193667 - }, - { - "lng": 7.477800721737151, - "lat": 46.97460750861006 - }, - { - "lng": 7.47778559733606, - "lat": 46.974615769743735 - }, - { - "lng": 7.477771728776835, - "lat": 46.97462500577891 - } - ] - }, - "altitude_lower": { - "value": 605.0, - "reference": "W84", - "units": "M" - }, - "altitude_upper": { - "value": 635.0, - "reference": "W84", - "units": "M" - } - }, - "time_start": { - "value": "2023-02-12T10:27:14.483425+00:00", - "format": "RFC3339" - }, - "time_end": { - "value": "2023-02-12T10:52:14.483425+00:00", - "format": "RFC3339" - } - } - ], - "state": "Accepted", - "off_nominal_volumes": [], - "priority": 100 - }, - "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://uav.com/emergency", - "operator_id": "CHEo5kut30e0mt01-qwe", - "uas_id": "", - "uas_type_certificate": "" - } - } - } - }, - "flight_2_activated_vol_A": { - "delta": { - "source": "flight_2_planned_vol_A", - "mutation": { - "request": { - "operational_intent": { - "state": "Activated" - } - } - } - } - }, - "flight_2_activated_vol_B": { - "delta": { - "source": "flight_2_activated_vol_A", - "mutation": { - "request": { - "operational_intent": { - "volumes": [ - { - "volume": { - "altitude_lower": { - "value": 650.0 - }, - "altitude_upper": { - "value": 705.0 - } - } - } - ] - } - } - } - } - }, - "flight_2_equal_prio_planned_vol_B": { - "delta": { - "source": "flight_2_activated_vol_B", - "mutation": { - "request": { - "operational_intent": { - "state": "Accepted", - "priority": 0 - } - } - } - } - }, - "flight_2_equal_prio_activated_vol_B": { - "delta": { - "source": "flight_2_equal_prio_planned_vol_B", - "mutation": { - "request": { - "operational_intent": { - "state": "Activated" - } - } - } - } - }, - "flight_2_equal_prio_nonconforming_vol_A": { - "delta": { - "source": "flight_2_equal_prio_activated_vol_B", - "mutation": { - "request": { - "operational_intent": { - "state": "Nonconforming", - "off_nominal_volumes": [ - { - "volume": { - "outline_polygon": { - "vertices": [ - { - "lng": 7.474315728091042, - "lat": 46.97716400145211 - }, - { - "lng": 7.474303247689658, - "lat": 46.97717412304557 - }, - { - "lng": 7.474292276891787, - "lat": 46.9771850331586 - }, - { - "lng": 7.474282921352688, - "lat": 46.97719662672131 - }, - { - "lng": 7.474275271172041, - "lat": 46.97720879208173 - }, - { - "lng": 7.474269400026217, - "lat": 46.97722141208117 - }, - { - "lng": 7.4742653644586845, - "lat": 46.977234365182404 - }, - { - "lng": 7.474263203335437, - "lat": 46.97724752664021 - }, - { - "lng": 7.474262937470636, - "lat": 46.97726076970267 - }, - { - "lng": 7.474264569426098, - "lat": 46.97727396683188 - }, - { - "lng": 7.47426808348659, - "lat": 46.97728699093222 - }, - { - "lng": 7.474273445811106, - "lat": 46.97729971657432 - }, - { - "lng": 7.474280604758724, - "lat": 46.97731202120303 - }, - { - "lng": 7.4742894913859015, - "lat": 46.97732378631779 - }, - { - "lng": 7.47430002011039, - "lat": 46.977334898613684 - }, - { - "lng": 7.474312089535409, - "lat": 46.97734525107282 - }, - { - "lng": 7.4743255834261335, - "lat": 46.97735474399491 - }, - { - "lng": 7.47434037182908, - "lat": 46.977363285957416 - }, - { - "lng": 7.474356312323634, - "lat": 46.97737079469613 - }, - { - "lng": 7.47437325139364, - "lat": 46.977377197897326 - }, - { - "lng": 7.474391025905868, - "lat": 46.97738243389426 - }, - { - "lng": 7.474409464681103, - "lat": 46.977386452261086 - }, - { - "lng": 7.474428390142731, - "lat": 46.97738921429845 - }, - { - "lng": 7.4744476200269405, - "lat": 46.97739069340619 - }, - { - "lng": 7.474466969138073, - "lat": 46.97739087533958 - }, - { - "lng": 7.474486251132214, - "lat": 46.97738975834647 - }, - { - "lng": 7.474505280311834, - "lat": 46.97738735318418 - }, - { - "lng": 7.47452387341421, - "lat": 46.97738368301589 - }, - { - "lng": 7.474541851376407, - "lat": 46.97737878318756 - }, - { - "lng": 7.474559041059788, - "lat": 46.97737270088755 - }, - { - "lng": 7.474575276917473, - "lat": 46.9773654946921 - }, - { - "lng": 7.474590402588685, - "lat": 46.977357234001225 - }, - { - "lng": 7.474604272404609, - "lat": 46.97734799837037 - }, - { - "lng": 7.4780602717187445, - "lat": 46.97480899404357 - }, - { - "lng": 7.478072750859629, - "lat": 46.97479887202181 - }, - { - "lng": 7.47808372039712, - "lat": 46.97478796152745 - }, - { - "lng": 7.478093074689058, - "lat": 46.97477636763495 - }, - { - "lng": 7.478100723649223, - "lat": 46.97476420200029 - }, - { - "lng": 7.478106593614889, - "lat": 46.974751581785505 - }, - { - "lng": 7.478110628056212, - "lat": 46.97473862853046 - }, - { - "lng": 7.4781127881205816, - "lat": 46.9747254669823 - }, - { - "lng": 7.478113053006759, - "lat": 46.97471222389403 - }, - { - "lng": 7.478111420165148, - "lat": 46.974699026803876 - }, - { - "lng": 7.478107905322289, - "lat": 46.97468600280696 - }, - { - "lng": 7.478102542329355, - "lat": 46.974673277331334 - }, - { - "lng": 7.478095382836098, - "lat": 46.97466097293006 - }, - { - "lng": 7.478086495793389, - "lat": 46.9746492081009 - }, - { - "lng": 7.478075966789133, - "lat": 46.97463809614524 - }, - { - "lng": 7.47806389722399, - "lat": 46.97462774407688 - }, - { - "lng": 7.478050403334804, - "lat": 46.97461825159139 - }, - { - "lng": 7.4780356150751714, - "lat": 46.97460971010614 - }, - { - "lng": 7.478019674863899, - "lat": 46.97460220187985 - }, - { - "lng": 7.478002736213457, - "lat": 46.97459579922035 - }, - { - "lng": 7.477984962251586, - "lat": 46.97459056378839 - }, - { - "lng": 7.477966524150307, - "lat": 46.974586546003664 - }, - { - "lng": 7.477947599477487, - "lat": 46.974583784559336 - }, - { - "lng": 7.477928370486799, - "lat": 46.97458230604945 - }, - { - "lng": 7.477909022362576, - "lat": 46.974582124712704 - }, - { - "lng": 7.4778897414364325, - "lat": 46.97458324229544 - }, - { - "lng": 7.47787071339284, - "lat": 46.974585648034825 - }, - { - "lng": 7.477852121480946, - "lat": 46.974589318762405 - }, - { - "lng": 7.477834144749823, - "lat": 46.974594219127326 - }, - { - "lng": 7.47781695632419, - "lat": 46.97460030193667 - }, - { - "lng": 7.477800721737151, - "lat": 46.97460750861006 - }, - { - "lng": 7.47778559733606, - "lat": 46.974615769743735 - }, - { - "lng": 7.477771728776835, - "lat": 46.97462500577891 - } - ] - }, - "altitude_lower": { - "value": 605.0, - "reference": "W84", - "units": "M" - }, - "altitude_upper": { - "value": 635.0, - "reference": "W84", - "units": "M" - } - }, - "time_start": { - "value": "2023-02-12T10:27:14.483425+00:00", - "format": "RFC3339" - }, - "time_end": { - "value": "2023-02-12T10:52:14.483425+00:00", - "format": "RFC3339" - } - } - ] - } - } - } - } - } - } -} diff --git a/schemas/Makefile b/schemas/Makefile index f2214ed280..08c2df14fb 100644 --- a/schemas/Makefile +++ b/schemas/Makefile @@ -1,9 +1,7 @@ .PHONY: format format: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black . ./manage_type_schemas.sh --generate .PHONY: lint lint: - docker run --rm -v "$(CURDIR):/code" -w /code pyfound/black:22.10.0 black --check . || (echo "Linter didn't succeed. You can use the following command to fix python linter issues: make format" && exit 1) ./manage_type_schemas.sh --check diff --git a/schemas/monitoring/monitorlib/fetch/Query.json b/schemas/monitoring/monitorlib/fetch/Query.json index 88c3188ed5..0255097971 100644 --- a/schemas/monitoring/monitorlib/fetch/Query.json +++ b/schemas/monitoring/monitorlib/fetch/Query.json @@ -7,6 +7,13 @@ "description": "Path to content that replaces the $ref", "type": "string" }, + "participant_id": { + "description": "If specified, identifier of the USS/participant hosting the server involved in this query.", + "type": [ + "string", + "null" + ] + }, "query_type": { "description": "If specified, the recognized type of this query.", "enum": [ @@ -50,13 +57,6 @@ }, "response": { "$ref": "ResponseDescription.json" - }, - "server_id": { - "description": "If specified, identifier of the USS/participant hosting the server involved in this query.", - "type": [ - "string", - "null" - ] } }, "required": [