diff --git a/monitoring/monitorlib/rid.py b/monitoring/monitorlib/rid.py index 3d2826de41..cf9bc67453 100644 --- a/monitoring/monitorlib/rid.py +++ b/monitoring/monitorlib/rid.py @@ -237,3 +237,19 @@ def flights_url_of(self, base_url: str) -> str: return base_url + flights_path else: raise ValueError("Unsupported RID version '{}'".format(self)) + + def scope_dp(self) -> str: + if self == RIDVersion.f3411_19: + return v19.constants.Scope.Read + elif self == RIDVersion.f3411_22a: + return v22a.constants.Scope.DisplayProvider + else: + raise ValueError("Unsupported RID version '{}'".format(self)) + + def scope_sp(self) -> str: + if self == RIDVersion.f3411_19: + return v19.constants.Scope.Write + elif self == RIDVersion.f3411_22a: + return v22a.constants.Scope.ServiceProvider + else: + raise ValueError("Unsupported RID version '{}'".format(self)) diff --git a/monitoring/uss_qualifier/README.md b/monitoring/uss_qualifier/README.md index ca69fe2888..a58199ab18 100644 --- a/monitoring/uss_qualifier/README.md +++ b/monitoring/uss_qualifier/README.md @@ -38,6 +38,12 @@ Part of a configuration defines artifacts that should be produced by the test ru See the [local testing page](local_testing.md) for more information regarding running uss_qualifier on a single local system. +## Troubleshooting + +### Skipped actions + +uss_qualifier is generally designed to skip test components when some prerequisites for those components are not met to enable testing of other parts of the systems under test until those prerequisites can be met. Components are generally skipped when a necessary resource is not provided. If you believe you have provided the resource that is claimed not to be provided, it is possible the resource could not be created due to another prerequisite not being met. See console warnings at the beginning of test execution for more information, and/or set [`stop_when_resource_not_created`](./configurations/configuration.py) to `true` in your configuration's `execution` configuration to stop test execution when such a prerequisite is not met. + ## Architecture * [Test suites](suites/README.md) diff --git a/monitoring/uss_qualifier/configurations/configuration.py b/monitoring/uss_qualifier/configurations/configuration.py index fe0374b789..9359674fdb 100644 --- a/monitoring/uss_qualifier/configurations/configuration.py +++ b/monitoring/uss_qualifier/configurations/configuration.py @@ -129,6 +129,9 @@ class ExecutionConfiguration(ImplicitDict): stop_fast: Optional[bool] = False """If true, escalate the Severity of any failed check to Critical in order to end the test run early.""" + stop_when_resource_not_created: Optional[bool] = False + """If true, stop test execution if one of the resources cannot be created. Otherwise, resources that cannot be created due to missing prerequisites are simply treated as omitted.""" + class TestConfiguration(ImplicitDict): action: TestSuiteActionDeclaration diff --git a/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml b/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml index fdf8365ab8..2e7401348a 100644 --- a/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml +++ b/monitoring/uss_qualifier/configurations/dev/f3548_self_contained.yaml @@ -36,6 +36,10 @@ v1: specification: # To avoid putting secrets in configuration files, the auth spec (including sensitive information) will be read from the AUTH_SPEC environment variable environment_variable_containing_auth_spec: AUTH_SPEC + scopes_authorized: + # InterUSS flight_planning v1 automated testing API + - interuss.flight_planning.direct_automated_test + - interuss.flight_planning.plan # Means by which uss_qualifier can discover which subscription ('sub' claim of its tokes) it is described by utm_client_identity: @@ -60,6 +64,7 @@ v1: resource_type: resources.communications.AuthAdapterResource specification: environment_variable_containing_auth_spec: AUTH_SPEC_2 + scopes_authorized: [] # Set of USSs capable of being tested as flight planners flight_planners: diff --git a/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml b/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml index 6847d6629f..753808078f 100644 --- a/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml +++ b/monitoring/uss_qualifier/configurations/dev/library/environment_containers.yaml @@ -8,12 +8,36 @@ utm_auth: resource_type: resources.communications.AuthAdapterResource specification: environment_variable_containing_auth_spec: AUTH_SPEC + scopes_authorized: + # InterUSS RIDv1 automated testing API + - rid.inject_test_data + - dss.read.identification_service_areas + # ASTM F3411-22a USS emulation roles + - rid.service_provider + - rid.display_provider + # ASTM F3411-19 USS emulation roles + - dss.write.identification_service_areas + - dss.read.identification_service_areas + # InterUSS flight_planning v1 automated testing API + - interuss.flight_planning.direct_automated_test + - interuss.flight_planning.plan + # Legacy InterUSS scd injection v1 automated testing API + - utm.inject_test_data + # ASTM F3548-21 USS emulation roles (not yet programatically constrained) +# - utm.strategic_coordination +# - utm.constraint_management +# - utm.constraint_processing +# - utm.conformance_monitoring_sa +# - utm.availability_arbitration + # InterUSS versioning automated testing API (not yet programatically constrained) +# - interuss.versioning.read_system_versions second_utm_auth: $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json resource_type: resources.communications.AuthAdapterResource specification: environment_variable_containing_auth_spec: AUTH_SPEC_2 + scopes_authorized: [] utm_client_identity: $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json diff --git a/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml b/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml index 6af9f2cba8..8458c390a7 100644 --- a/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml +++ b/monitoring/uss_qualifier/configurations/dev/library/environment_localhost.yaml @@ -8,12 +8,36 @@ utm_auth: resource_type: resources.communications.AuthAdapterResource specification: environment_variable_containing_auth_spec: AUTH_SPEC + scopes_authorized: + # InterUSS RIDv1 automated testing API + - rid.inject_test_data + - dss.read.identification_service_areas + # ASTM F3411-22a USS emulation roles + - rid.service_provider + - rid.display_provider + # ASTM F3411-19 USS emulation roles + - dss.write.identification_service_areas + - dss.read.identification_service_areas + # InterUSS flight_planning v1 automated testing API + - interuss.flight_planning.direct_automated_test + - interuss.flight_planning.plan + # Legacy InterUSS scd injection v1 automated testing API + - utm.inject_test_data + # ASTM F3548-21 USS emulation roles (not yet programatically constrained) +# - utm.strategic_coordination +# - utm.constraint_management +# - utm.constraint_processing +# - utm.conformance_monitoring_sa +# - utm.availability_arbitration + # InterUSS versioning automated testing API (not yet programatically constrained) +# - interuss.versioning.read_system_versions second_utm_auth: $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json resource_type: resources.communications.AuthAdapterResource specification: environment_variable_containing_auth_spec: AUTH_SPEC_2 + scopes_authorized: [] utm_client_identity: $content_schema: monitoring/uss_qualifier/resources/definitions/ResourceDeclaration.json diff --git a/monitoring/uss_qualifier/configurations/dev/uspace.yaml b/monitoring/uss_qualifier/configurations/dev/uspace.yaml index 69247f0396..bacfcb9a2d 100644 --- a/monitoring/uss_qualifier/configurations/dev/uspace.yaml +++ b/monitoring/uss_qualifier/configurations/dev/uspace.yaml @@ -51,16 +51,16 @@ v1: invalid_flight_intents: che_invalid_flight_intents invalid_flight_auth_flights: che_invalid_flight_auth_flights non_conflicting_flights: che_non_conflicting_flights - flight_planners: all_flight_planners + flight_planners: all_flight_planners? mock_uss: mock_uss_instance_uss6 scd_dss: scd_dss scd_dss_instances: scd_dss_instances flights_data: foca_flights_data - service_providers: netrid_service_providers_v22a + service_providers: netrid_service_providers_v22a? observers: netrid_observers_v22a evaluation_configuration: netrid_observation_evaluation_configuration - netrid_dss_instances: netrid_dss_instances_v22a + netrid_dss_instances: netrid_dss_instances_v22a? utm_client_identity: utm_client_identity second_utm_auth: second_utm_auth id_generator: id_generator @@ -80,16 +80,16 @@ v1: invalid_flight_intents: invalid_flight_intents invalid_flight_auth_flights: invalid_flight_auth_flights non_conflicting_flights: non_conflicting_flights - flight_planners: flight_planners + flight_planners: flight_planners? mock_uss: mock_uss scd_dss: scd_dss scd_dss_instances: scd_dss_instances flights_data: flights_data - service_providers: service_providers + service_providers: service_providers? observers: observers evaluation_configuration: evaluation_configuration - netrid_dss_instances: netrid_dss_instances + netrid_dss_instances: netrid_dss_instances? utm_client_identity: utm_client_identity second_utm_auth: second_utm_auth id_generator: id_generator diff --git a/monitoring/uss_qualifier/main.py b/monitoring/uss_qualifier/main.py index 20458b4406..7d53df09bc 100644 --- a/monitoring/uss_qualifier/main.py +++ b/monitoring/uss_qualifier/main.py @@ -74,7 +74,15 @@ def execute_test_run(whole_config: USSQualifierConfiguration): logger.info(f"Codebase version {codebase_version}, commit hash {commit_hash}") logger.info("Instantiating resources") - resources = create_resources(config.resources.resource_declarations) + stop_when_not_created = ( + "execution" in config + and config.execution + and "stop_when_resource_not_created" in config.execution + and config.execution.stop_when_resource_not_created + ) + resources = create_resources( + config.resources.resource_declarations, stop_when_not_created + ) logger.info("Computing signatures of inputs") if config.non_baseline_inputs: @@ -127,7 +135,7 @@ def run_config( for e in validation_errors: logger.error("[{}]: {}", e.json_path, e.message) raise ValueError( - f"{len(validation_errors)} validation errors indicated above. Hint: resolve the clearest error first and then rerun validation." + f"{len(validation_errors)} test configuration validation errors indicated above. Hint: resolve the clearest error first and then rerun validation." ) whole_config = ImplicitDict.parse(config_src, USSQualifierConfiguration) diff --git a/monitoring/uss_qualifier/resources/astm/f3411/dss.py b/monitoring/uss_qualifier/resources/astm/f3411/dss.py index 1595864d70..e1737ddacb 100644 --- a/monitoring/uss_qualifier/resources/astm/f3411/dss.py +++ b/monitoring/uss_qualifier/resources/astm/f3411/dss.py @@ -89,6 +89,17 @@ class DSSInstanceResource(Resource[DSSInstanceSpecification]): def __init__( self, specification: DSSInstanceSpecification, auth_adapter: AuthAdapterResource ): + # Note that the current implementation does not support acting as just a + # SP accessing the DSS or just a DP accessing the DSS, but this could be + # improved. + auth_adapter.assert_scopes_available( + scopes_required={ + specification.rid_version.scope_sp(): "act as an ASTM F3411 NetRID Service Provider to facilitate testing", + specification.rid_version.scope_dp(): "act as an ASTM F3411 NetRID Display Provider to facilitate testing", + }, + consumer_name=f"{self.__class__.__name__} resource", + ) + self.dss_instance = DSSInstance( specification.participant_id, specification.base_url, @@ -118,13 +129,6 @@ def __init__( auth_adapter: AuthAdapterResource, ): self.dss_instances = [ - DSSInstance( - s.participant_id, - s.base_url, - s.has_private_address, - s.local_debug, - s.rid_version, - auth_adapter.adapter, - ) + DSSInstanceResource(s, auth_adapter).dss_instance for s in specification.dss_instances ] diff --git a/monitoring/uss_qualifier/resources/communications/auth_adapter.py b/monitoring/uss_qualifier/resources/communications/auth_adapter.py index f3ba0ca28b..2b20c688e0 100644 --- a/monitoring/uss_qualifier/resources/communications/auth_adapter.py +++ b/monitoring/uss_qualifier/resources/communications/auth_adapter.py @@ -1,17 +1,21 @@ import os -from typing import Optional +from enum import Enum +from typing import Optional, List, Set, Dict from implicitdict import ImplicitDict from monitoring.monitorlib.auth import make_auth_adapter from monitoring.monitorlib import infrastructure +from monitoring.uss_qualifier.resources.resource import MissingResourceError from monitoring.uss_qualifier.resources.resource import Resource class AuthAdapterSpecification(ImplicitDict): """Specification for an AuthAdapter resource. - Exactly one of the fields defined must be populated. + Exactly one of these fields must be populated: + * auth_spec + * environment_variable_containing_auth_spec """ auth_spec: Optional[str] @@ -20,9 +24,13 @@ class AuthAdapterSpecification(ImplicitDict): environment_variable_containing_auth_spec: Optional[str] """Name of environment variable containing the auth spec. This is the preferred method of providing the auth spec.""" + scopes_authorized: List[str] + """List of scopes the user in the auth spec is authorized to obtain.""" + class AuthAdapterResource(Resource[AuthAdapterSpecification]): adapter: infrastructure.AuthAdapter + scopes: Set[str] def __init__(self, specification: AuthAdapterSpecification): if ( @@ -44,3 +52,25 @@ def __init__(self, specification: AuthAdapterSpecification): else: raise ValueError("No auth spec was declared") self.adapter = make_auth_adapter(spec) + self.scopes = set(specification.scopes_authorized) + + def assert_scopes_available( + self, scopes_required: Dict[str, str], consumer_name: str + ) -> None: + """Raise a MissingResourceError if any of the scopes_required are not available. + + Args: + scopes_required: Dict relating scope required to a human description of why that scope is required. + consumer_name: Name of entity consuming/using this auth adapter with the scopes_required. + + Raises: + * MissingResourceError, if a required scope is not available. + """ + for scope, reason in scopes_required.items(): + if scope not in self.scopes: + if isinstance(scope, Enum): + scope = scope.value + raise MissingResourceError( + f"AuthAdapterResource provided to {consumer_name} is not declared (in its resource specification) as authorized to obtain scope `{scope}` which is required by {consumer_name} to {reason}. Update `scopes_authorized` to include `{scope}` to resolve this message. {len(self.scopes)} scopes already declared as authorized for AuthAdapterResource: {', '.join(self.scopes)}", + "", + ) diff --git a/monitoring/uss_qualifier/resources/flight_planning/flight_planner.py b/monitoring/uss_qualifier/resources/flight_planning/flight_planner.py index 81d34bb85d..b28e83845a 100644 --- a/monitoring/uss_qualifier/resources/flight_planning/flight_planner.py +++ b/monitoring/uss_qualifier/resources/flight_planning/flight_planner.py @@ -90,7 +90,7 @@ def to_client( ) -class FlightPlanner: +class FlightPlanner(object): """Manages the state and the interactions with flight planner USS. Note: this class will be deprecated in favor of FlightPlannerClient.""" diff --git a/monitoring/uss_qualifier/resources/flight_planning/flight_planners.py b/monitoring/uss_qualifier/resources/flight_planning/flight_planners.py index d61ad2351e..3e5db5e755 100644 --- a/monitoring/uss_qualifier/resources/flight_planning/flight_planners.py +++ b/monitoring/uss_qualifier/resources/flight_planning/flight_planners.py @@ -1,10 +1,14 @@ from typing import List, Iterable, Dict, Optional from implicitdict import ImplicitDict +from uas_standards.interuss.automated_testing.scd.v1.constants import Scope as ScopeSCD +from uas_standards.interuss.automated_testing.flight_planning.v1.constants import ( + Scope as ScopeFlightPlanning, +) + from monitoring.monitorlib.clients.flight_planning.client import FlightPlannerClient from monitoring.uss_qualifier.reports.report import ParticipantID from monitoring.uss_qualifier.resources.definitions import ResourceID - from monitoring.uss_qualifier.resources.resource import Resource from monitoring.uss_qualifier.resources.communications import AuthAdapterResource from monitoring.uss_qualifier.resources.flight_planning.flight_planner import ( @@ -27,6 +31,32 @@ def __init__( specification: FlightPlannerSpecification, auth_adapter: AuthAdapterResource, ): + if ( + "scd_injection_base_url" in specification.flight_planner + and specification.flight_planner.scd_injection_base_url + ): + auth_adapter.assert_scopes_available( + scopes_required={ + ScopeSCD.Inject: "inject user flight planning commands to USSs under test", + }, + consumer_name=f"{self.__class__.__name__} using legacy scd injection API", + ) + elif ( + "v1_base_url" in specification.flight_planner + and specification.flight_planner.v1_base_url + ): + auth_adapter.assert_scopes_available( + scopes_required={ + ScopeFlightPlanning.DirectAutomatedTest: "act as test director to instruct USSs under test to perform various test preparation activities related to flight planning testing", + ScopeFlightPlanning.Plan: "act as user performing flight planning operations on USSs under test", + }, + consumer_name=f"{self.__class__.__name__} using flight_planner v1 API", + ) + else: + raise NotImplementedError( + "The means by which to interact with the flight planner is not currently supported in FlightPlannerResource (neither scd_injection_base_url nor v1_base_url were specified)" + ) + self.flight_planner = FlightPlanner( specification.flight_planner, auth_adapter.adapter ) diff --git a/monitoring/uss_qualifier/resources/netrid/observers.py b/monitoring/uss_qualifier/resources/netrid/observers.py index b172672225..fa2c0b7b89 100644 --- a/monitoring/uss_qualifier/resources/netrid/observers.py +++ b/monitoring/uss_qualifier/resources/netrid/observers.py @@ -3,14 +3,15 @@ from loguru import logger import s2sphere from implicitdict import ImplicitDict +from uas_standards.interuss.automated_testing.rid.v1 import ( + observation as observation_api, +) +from uas_standards.interuss.automated_testing.rid.v1.constants import Scope from monitoring.monitorlib import fetch, infrastructure from monitoring.monitorlib.fetch import QueryType from monitoring.monitorlib.infrastructure import UTMClientSession from monitoring.monitorlib.rid import RIDVersion -from uas_standards.interuss.automated_testing.rid.v1 import ( - observation as observation_api, -) from monitoring.uss_qualifier.resources.resource import Resource from monitoring.uss_qualifier.resources.communications import AuthAdapterResource @@ -46,9 +47,7 @@ def observe_system( self.session, "GET", url, - # 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", + scope=Scope.Observe, participant_id=self.participant_id, ) try: @@ -71,9 +70,7 @@ def observe_flight_details( self.session, "GET", f"/display_data/{flight_id}", - # 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", + scope=Scope.Observe, participant_id=self.participant_id, ) # Record query metadata for later use in the aggregate checks @@ -119,6 +116,13 @@ def __init__( specification: NetRIDObserversSpecification, auth_adapter: AuthAdapterResource, ): + auth_adapter.assert_scopes_available( + scopes_required={ + Scope.Observe: "observe RID flights visible to user from USSs under test" + }, + consumer_name=self.__class__.__name__, + ) + self.observers = [ RIDSystemObserver( o.participant_id, diff --git a/monitoring/uss_qualifier/resources/netrid/service_providers.py b/monitoring/uss_qualifier/resources/netrid/service_providers.py index cdbc5a36ea..ae64ce3068 100644 --- a/monitoring/uss_qualifier/resources/netrid/service_providers.py +++ b/monitoring/uss_qualifier/resources/netrid/service_providers.py @@ -87,6 +87,13 @@ def __init__( specification: NetRIDServiceProvidersSpecification, auth_adapter: AuthAdapterResource, ): + auth_adapter.assert_scopes_available( + scopes_required={ + SCOPE_RID_QUALIFIER_INJECT: "inject RID test flight data into USSs under test" + }, + consumer_name=f"{self.__class__.__name__} resource", + ) + self.service_providers = [ NetRIDServiceProvider( participant_id=s.participant_id, diff --git a/monitoring/uss_qualifier/resources/resource.py b/monitoring/uss_qualifier/resources/resource.py index eaa86d4f63..879f529e97 100644 --- a/monitoring/uss_qualifier/resources/resource.py +++ b/monitoring/uss_qualifier/resources/resource.py @@ -1,7 +1,8 @@ from abc import ABC, abstractmethod -from typing import get_type_hints, Dict, Generic, Tuple, TypeVar, Type +from typing import get_type_hints, Dict, Generic, Set, Tuple, TypeVar, Type from implicitdict import ImplicitDict +from loguru import logger from monitoring import uss_qualifier as uss_qualifier_module from monitoring.monitorlib import inspection @@ -47,7 +48,8 @@ def __init__(self, msg: str, missing_resource_name: str): def create_resources( - resource_declarations: Dict[ResourceID, ResourceDeclaration] + resource_declarations: Dict[ResourceID, ResourceDeclaration], + stop_when_not_created: bool = False, ) -> Dict[ResourceID, ResourceType]: """Instantiate all resources from the provided declarations. @@ -56,37 +58,58 @@ def create_resources( Args: resource_declarations: Mapping between resource ID and declaration for that resource. + stop_when_not_created: If true, reraise any MissingResourceErrors encountered while creating resources. Returns: Mapping between resource ID and an instance of that declared resource. """ resource_pool: Dict[ResourceID, ResourceType] = {} + could_not_create: Set[ResourceID] = set() resources_created = 1 unmet_dependencies_by_resource = {} while resources_created > 0: resources_created = 0 for name, declaration in resource_declarations.items(): - if name in resource_pool: + if name in resource_pool or name in could_not_create: continue unmet_dependencies = [ - d for d in declaration.dependencies.values() if d not in resource_pool + d + for d in declaration.dependencies.values() + if d not in resource_pool and d not in could_not_create ] if unmet_dependencies: unmet_dependencies_by_resource[name] = unmet_dependencies else: - resource_pool[name] = _make_resource(declaration, resource_pool) - resources_created += 1 - - if len(resource_pool) != len(resource_declarations): + uncreated = [ + d + for d in declaration.dependencies.values() + if d in could_not_create + ] + if uncreated: + logger.warning( + f"Could not create resource `{name}` because it depends on resources that could not be created: {', '.join(uncreated)}" + ) + could_not_create.add(name) + else: + try: + resource_pool[name] = _make_resource(declaration, resource_pool) + resources_created += 1 + except MissingResourceError as e: + logger.warning( + f"Could not create resource `{name}` because {e}" + ) + if stop_when_not_created: + raise e + could_not_create.add(name) + + if len(resource_pool) + len(could_not_create) != len(resource_declarations): uncreated_resources = [ (r + " ({} missing)".format(", ".join(unmet_dependencies_by_resource[r]))) for r in resource_declarations - if r not in resource_pool + if r not in resource_pool and r not in could_not_create ] raise ValueError( - "Could not create resources: {} (do you have circular dependencies?)".format( - ", ".join(uncreated_resources) - ) + f"Could not create resources: {', '.join(uncreated_resources)} (do you have circular dependencies?)" ) return resource_pool diff --git a/monitoring/uss_qualifier/scenarios/scenario.py b/monitoring/uss_qualifier/scenarios/scenario.py index 964ead7fdb..bd2c07c855 100644 --- a/monitoring/uss_qualifier/scenarios/scenario.py +++ b/monitoring/uss_qualifier/scenarios/scenario.py @@ -185,7 +185,9 @@ class GenericTestScenario(ABC): _case_report: Optional[TestCaseReport] = None _current_step: Optional[TestStepDocumentation] = None _step_report: Optional[TestStepReport] = None - _allow_undocumented_checks = False # When this variable is set to True, it allows undocumented checks to be executed by the scenario. This is primarly intended to simplify internal unit testing. + + _allow_undocumented_checks = False + """When this variable is set to True, it allows undocumented checks to be executed by the scenario. This is primarly intended to simplify internal unit testing.""" context = None """Execution context; set at begin_test_scenario.""" diff --git a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.yaml b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.yaml index 8899afe452..2beaa7178e 100644 --- a/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.yaml +++ b/monitoring/uss_qualifier/suites/astm/netrid/f3411_22a.yaml @@ -1,10 +1,10 @@ name: ASTM F3411-22a resources: flights_data: resources.netrid.FlightDataResource - service_providers: resources.netrid.NetRIDServiceProviders + service_providers: resources.netrid.NetRIDServiceProviders? observers: resources.netrid.NetRIDObserversResource evaluation_configuration: resources.netrid.EvaluationConfigurationResource - dss_instances: resources.astm.f3411.DSSInstancesResource + dss_instances: resources.astm.f3411.DSSInstancesResource? utm_client_identity: resources.communications.ClientIdentityResource id_generator: resources.interuss.IDGeneratorResource service_area: resources.netrid.ServiceAreaResource @@ -40,7 +40,7 @@ actions: service_providers: service_providers observers: observers evaluation_configuration: evaluation_configuration - dss_pool: dss_instances + dss_pool: dss_instances? on_failure: Continue - test_scenario: scenario_type: scenarios.astm.netrid.v22a.Misbehavior diff --git a/monitoring/uss_qualifier/suites/uspace/flight_auth.yaml b/monitoring/uss_qualifier/suites/uspace/flight_auth.yaml index dd57cdd671..895af0fed4 100644 --- a/monitoring/uss_qualifier/suites/uspace/flight_auth.yaml +++ b/monitoring/uss_qualifier/suites/uspace/flight_auth.yaml @@ -5,7 +5,7 @@ resources: invalid_flight_auth_flights: resources.flight_planning.FlightIntentsResource invalid_flight_intents: resources.flight_planning.FlightIntentsResource non_conflicting_flights: resources.flight_planning.FlightIntentsResource - flight_planners: resources.flight_planning.FlightPlannersResource + flight_planners: resources.flight_planning.FlightPlannersResource? mock_uss: resources.interuss.mock_uss.client.MockUSSResource? dss: resources.astm.f3548.v21.DSSInstanceResource dss_instances: resources.astm.f3548.v21.DSSInstancesResource? @@ -19,7 +19,7 @@ actions: priority_preemption_flights: priority_preemption_flights invalid_flight_intents: invalid_flight_intents non_conflicting_flights: non_conflicting_flights - flight_planners: flight_planners + flight_planners: flight_planners? mock_uss: mock_uss dss: dss dss_instances: dss_instances diff --git a/monitoring/uss_qualifier/suites/uspace/network_identification.yaml b/monitoring/uss_qualifier/suites/uspace/network_identification.yaml index d07ce5578e..620ac0097c 100644 --- a/monitoring/uss_qualifier/suites/uspace/network_identification.yaml +++ b/monitoring/uss_qualifier/suites/uspace/network_identification.yaml @@ -1,10 +1,10 @@ name: U-Space network identification resources: flights_data: resources.netrid.FlightDataResource - service_providers: resources.netrid.NetRIDServiceProviders + service_providers: resources.netrid.NetRIDServiceProviders? observers: resources.netrid.NetRIDObserversResource evaluation_configuration: resources.netrid.EvaluationConfigurationResource - dss_instances: resources.astm.f3411.DSSInstancesResource + dss_instances: resources.astm.f3411.DSSInstancesResource? utm_client_identity: resources.communications.ClientIdentityResource id_generator: resources.interuss.IDGeneratorResource service_area: resources.netrid.ServiceAreaResource @@ -14,10 +14,10 @@ actions: suite_type: suites.astm.netrid.f3411_22a resources: flights_data: flights_data - service_providers: service_providers + service_providers: service_providers? observers: observers evaluation_configuration: evaluation_configuration - dss_instances: dss_instances + dss_instances: dss_instances? utm_client_identity: utm_client_identity id_generator: id_generator service_area: service_area diff --git a/monitoring/uss_qualifier/suites/uspace/required_services.yaml b/monitoring/uss_qualifier/suites/uspace/required_services.yaml index ace8ff2c31..987d70090f 100644 --- a/monitoring/uss_qualifier/suites/uspace/required_services.yaml +++ b/monitoring/uss_qualifier/suites/uspace/required_services.yaml @@ -7,18 +7,18 @@ resources: invalid_flight_intents: resources.flight_planning.FlightIntentsResource invalid_flight_auth_flights: resources.flight_planning.FlightIntentsResource non_conflicting_flights: resources.flight_planning.FlightIntentsResource - flight_planners: resources.flight_planning.FlightPlannersResource + flight_planners: resources.flight_planning.FlightPlannersResource? mock_uss: resources.interuss.mock_uss.client.MockUSSResource? scd_dss: resources.astm.f3548.v21.DSSInstanceResource scd_dss_instances: resources.astm.f3548.v21.DSSInstancesResource? flights_data: resources.netrid.FlightDataResource - service_providers: resources.netrid.NetRIDServiceProviders + service_providers: resources.netrid.NetRIDServiceProviders? observers: resources.netrid.NetRIDObserversResource evaluation_configuration: resources.netrid.EvaluationConfigurationResource - netrid_dss_instances: resources.astm.f3411.DSSInstancesResource + netrid_dss_instances: resources.astm.f3411.DSSInstancesResource? utm_client_identity: resources.communications.ClientIdentityResource - second_utm_auth: resources.communications.AuthAdapterResource + second_utm_auth: resources.communications.AuthAdapterResource? id_generator: resources.interuss.IDGeneratorResource service_area: resources.netrid.ServiceAreaResource problematically_big_area: resources.VerticesResource @@ -42,21 +42,21 @@ actions: invalid_flight_intents: invalid_flight_intents invalid_flight_auth_flights: invalid_flight_auth_flights non_conflicting_flights: non_conflicting_flights - flight_planners: flight_planners + flight_planners: flight_planners? mock_uss: mock_uss dss: scd_dss dss_instances: scd_dss_instances id_generator: id_generator - second_utm_auth: second_utm_auth + second_utm_auth: second_utm_auth? on_failure: Continue - test_suite: suite_type: suites.uspace.network_identification resources: flights_data: flights_data - service_providers: service_providers + service_providers: service_providers? observers: observers evaluation_configuration: evaluation_configuration - dss_instances: netrid_dss_instances + dss_instances: netrid_dss_instances? utm_client_identity: utm_client_identity id_generator: id_generator service_area: service_area diff --git a/schemas/monitoring/uss_qualifier/configurations/configuration/ExecutionConfiguration.json b/schemas/monitoring/uss_qualifier/configurations/configuration/ExecutionConfiguration.json index 103698bbbd..67b97af811 100644 --- a/schemas/monitoring/uss_qualifier/configurations/configuration/ExecutionConfiguration.json +++ b/schemas/monitoring/uss_qualifier/configurations/configuration/ExecutionConfiguration.json @@ -33,6 +33,13 @@ "boolean", "null" ] + }, + "stop_when_resource_not_created": { + "description": "If true, stop test execution if one of the resources cannot be created. Otherwise, resources that cannot be created due to missing prerequisites are simply treated as omitted.", + "type": [ + "boolean", + "null" + ] } }, "type": "object" diff --git a/schemas/monitoring/uss_qualifier/resources/communications/auth_adapter/AuthAdapterSpecification.json b/schemas/monitoring/uss_qualifier/resources/communications/auth_adapter/AuthAdapterSpecification.json index aca02c7a45..bb01460d42 100644 --- a/schemas/monitoring/uss_qualifier/resources/communications/auth_adapter/AuthAdapterSpecification.json +++ b/schemas/monitoring/uss_qualifier/resources/communications/auth_adapter/AuthAdapterSpecification.json @@ -1,7 +1,7 @@ { "$id": "https://github.com/interuss/monitoring/blob/main/schemas/monitoring/uss_qualifier/resources/communications/auth_adapter/AuthAdapterSpecification.json", "$schema": "https://json-schema.org/draft/2020-12/schema", - "description": "Specification for an AuthAdapter resource.\n\nExactly one of the fields defined must be populated.\n\nmonitoring.uss_qualifier.resources.communications.auth_adapter.AuthAdapterSpecification, as defined in monitoring/uss_qualifier/resources/communications/auth_adapter.py", + "description": "Specification for an AuthAdapter resource.\n\nExactly one of these fields must be populated:\n * auth_spec\n * environment_variable_containing_auth_spec\n\nmonitoring.uss_qualifier.resources.communications.auth_adapter.AuthAdapterSpecification, as defined in monitoring/uss_qualifier/resources/communications/auth_adapter.py", "properties": { "$ref": { "description": "Path to content that replaces the $ref", @@ -20,7 +20,17 @@ "string", "null" ] + }, + "scopes_authorized": { + "description": "List of scopes the user in the auth spec is authorized to obtain.", + "items": { + "type": "string" + }, + "type": "array" } }, + "required": [ + "scopes_authorized" + ], "type": "object" } \ No newline at end of file