Skip to content

Commit

Permalink
UTM DSS0300
Browse files Browse the repository at this point in the history
  • Loading branch information
Shastick committed Oct 10, 2023
1 parent b171492 commit 4b0dff0
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 11 deletions.
1 change: 1 addition & 0 deletions monitoring/uss_qualifier/configurations/dev/f3548.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ v1:
priority_preemption_flights: priority_preemption_flights
invalid_flight_intents: invalid_flight_intents
dss: dss
all_dss_instances: dss_instances
artifacts:
tested_roles:
report_path: output/tested_roles_f3548
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,19 @@ f3548:
participant_id: uss1
base_url: http://dss.uss1.localutm
has_private_address: true
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: false
- participant_id: uss2
base_url: http://dss.uss2.localutm
has_private_address: false

f3548_single_scenario:
uss1:
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .dss import DSSInstanceResource
from .dss import DSSInstanceResource, DSSInstancesResource
48 changes: 45 additions & 3 deletions monitoring/uss_qualifier/resources/astm/f3548/v21/dss.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Tuple, List
from __future__ import annotations
from typing import Tuple, List, Optional
from urllib.parse import urlparse

from implicitdict import ImplicitDict
Expand All @@ -24,6 +25,9 @@ class DSSInstanceSpecification(ImplicitDict):
base_url: str
"""Base URL for the DSS instance according to the ASTM F3548-21 API"""

has_private_address: Optional[bool]
"""Whether this DSS instance is expected to have a private address that is not publicly addressable."""

def __init__(self, *args, **kwargs):
super().__init__(**kwargs)
try:
Expand All @@ -34,16 +38,21 @@ def __init__(self, *args, **kwargs):

class DSSInstance(object):
participant_id: str
base_url: str
has_private_address: bool = False
client: infrastructure.UTMClientSession

def __init__(
self,
participant_id: str,
base_url: str,
has_private_address: Optional[bool],
auth_adapter: infrastructure.AuthAdapter,
):
self.participant_id = participant_id
self._base_url = base_url
self.base_url = base_url
if has_private_address is not None:
self.has_private_address = has_private_address
self.client = infrastructure.UTMClientSession(base_url, auth_adapter)

def find_op_intent(
Expand Down Expand Up @@ -82,6 +91,13 @@ def get_full_op_intent(
).operational_intent
return result, query

def is_same_as(self, other: DSSInstance) -> bool:
return (
self.participant_id == other.participant_id
and self.base_url == other.base_url
and self.has_private_address == other.has_private_address
)


class DSSInstanceResource(Resource[DSSInstanceSpecification]):
dss: DSSInstance
Expand All @@ -92,5 +108,31 @@ def __init__(
auth_adapter: AuthAdapterResource,
):
self.dss = DSSInstance(
specification.participant_id, specification.base_url, auth_adapter.adapter
specification.participant_id,
specification.base_url,
specification.has_private_address,
auth_adapter.adapter,
)


class DSSInstancesSpecification(ImplicitDict):
dss_instances: List[DSSInstanceSpecification]


class DSSInstancesResource(Resource[DSSInstancesSpecification]):
dss_instances: List[DSSInstance]

def __init__(
self,
specification: DSSInstancesSpecification,
auth_adapter: AuthAdapterResource,
):
self.dss_instances = [
DSSInstance(
s.participant_id,
s.base_url,
s.has_private_address,
auth_adapter.adapter,
)
for s in specification.dss_instances
]
1 change: 1 addition & 0 deletions monitoring/uss_qualifier/scenarios/astm/utm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from .nominal_planning.conflict_equal_priority_not_permitted.conflict_equal_priority_not_permitted import (
ConflictEqualPriorityNotPermitted,
)
from .dss_interoperability import DSSInteroperability
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ASTM F3548-21 UTM DSS interoperability test scenario

## Overview

TODO: Complete with details once we check more than the prerequisites.

This scenario currently only checks that all specified DSS instances are publicly addressable and reachable.

## Resources

### primary_dss_instance

A resources.astm.f3548.v21.DSSInstanceResource containing the "primary" DSS instance for this scenario.

### all_dss_instances

A resources.astm.f3548.v21.DSSInstancesResource containing at least two DSS instances complying with ASTM F3548-21.

## Prerequisites test case

### Test environment requirements test step

#### DSS instance is publicly addressable check

As per **[astm.f3548.v21.DSS0300](../../../requirements/astm/f3548/v21.md)** the DSS instance should be publicly addressable.
As such, this check will fail if the resolved IP of the DSS host is a private IP address, unless that is explicitly
expected.

#### DSS instance is reachable check
As per **[astm.f3548.v21.DSS0300](../../../requirements/astm/f3548/v21.md)** the DSS instance should be publicly addressable.
As such, this check will fail if the DSS is not reachable with a dummy query.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import ipaddress
import socket
import time
import uuid
from dataclasses import dataclass
import datetime
from enum import Enum
from typing import List, Dict, Optional
from urllib.parse import urlparse

import s2sphere
from uas_standards.astm.f3548.v21.api import Volume4D, Volume3D, Polygon, LatLngPoint

from monitoring.monitorlib.fetch.rid import ISA
from monitoring.uss_qualifier.common_data_definitions import Severity
from monitoring.uss_qualifier.resources.astm.f3548.v21.dss import (
DSSInstancesResource,
DSSInstanceResource,
DSSInstance,
)
from monitoring.uss_qualifier.scenarios.astm.netrid.dss_wrapper import DSSWrapper
from monitoring.uss_qualifier.scenarios.scenario import TestScenario

VERTICES: List[LatLngPoint] = [
LatLngPoint(lng=130.6205, lat=-23.6558),
LatLngPoint(lng=130.6301, lat=-23.6898),
LatLngPoint(lng=130.6700, lat=-23.6709),
LatLngPoint(lng=130.6466, lat=-23.6407),
]
SHORT_WAIT_SEC = 5


class DSSInteroperability(
TestScenario
): # TODO needed to extend TestScenario instead of GenericTestScenario otherwise `make format` is unhappy
_dss_primary: DSSInstance
_dss_others: List[DSSInstance]

def __init__(
self,
primary_dss_instance: DSSInstanceResource,
all_dss_instances: DSSInstancesResource,
):
super().__init__()
self._dss_primary = primary_dss_instance.dss
self._dss_others = [
dss
for dss in all_dss_instances.dss_instances
if not dss.is_same_as(primary_dss_instance.dss)
]

def run(self):

# self.record_note(
# "dss_instances",
# f"Provided DSS instances: {[self._dss_primary] + self._dss_others}",
# )
self.begin_test_scenario()

self.begin_test_case("Prerequisites")

self.begin_test_step("Test environment requirements")
self._test_env_reqs()
self.end_test_step()

self.end_test_case()

self.end_test_scenario()

def _test_env_reqs(self):
for dss in [self._dss_primary] + self._dss_others:
with self.check(
"DSS instance is publicly addressable", [dss.participant_id]
) as check:
parsed_url = urlparse(dss.base_url)
ip_addr = socket.gethostbyname(parsed_url.hostname)

if dss.has_private_address:
self.record_note(
f"{dss.participant_id}_private_address",
f"DSS instance (URL: {dss.base_url}, netloc: {parsed_url.netloc}, resolved IP: {ip_addr}) is declared as explicitly having a private address, skipping check",
)
elif ipaddress.ip_address(ip_addr).is_private:
check.record_failed(
summary=f"DSS host {parsed_url.netloc} is not publicly addressable",
severity=Severity.Medium,
participants=[dss.participant_id],
details=f"DSS (URL: {dss.base_url}, netloc: {parsed_url.netloc}, resolved IP: {ip_addr}) is not publicly addressable",
)

with self.check("DSS instance is reachable", [dss.participant_id]) as check:
# dummy search query
dss.find_op_intent(
extent=Volume4D(
volume=Volume3D(outline_polygon=Polygon(vertices=VERTICES))
)
)
14 changes: 10 additions & 4 deletions monitoring/uss_qualifier/suites/astm/utm/f3548_21.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

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

1. Action generator: [`action_generators.flight_planning.FlightPlannerCombinations`](../../../action_generators/flight_planning/planner_combinations.py)
1. Scenario: [Validation of operational intents](../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md) ([`scenarios.astm.utm.FlightIntentValidation`](../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.py))
1. Scenario: [ASTM F3548-21 UTM DSS interoperability](../../../scenarios/astm/utm/dss_interoperability.md) ([`scenarios.astm.utm.DSSInteroperability`](../../../scenarios/astm/utm/dss_interoperability.py))
2. Action generator: [`action_generators.flight_planning.FlightPlannerCombinations`](../../../action_generators/flight_planning/planner_combinations.py)
1. Scenario: [Nominal planning: conflict with higher priority](../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md) ([`scenarios.astm.utm.ConflictHigherPriority`](../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.py))
1. Scenario: [Validation of operational intents](../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md) ([`scenarios.astm.utm.FlightIntentValidation`](../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.py))
3. Action generator: [`action_generators.flight_planning.FlightPlannerCombinations`](../../../action_generators/flight_planning/planner_combinations.py)
1. Scenario: [Nominal planning: conflict with higher priority](../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md) ([`scenarios.astm.utm.ConflictHigherPriority`](../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.py))
4. Action generator: [`action_generators.flight_planning.FlightPlannerCombinations`](../../../action_generators/flight_planning/planner_combinations.py)
1. Scenario: [Nominal planning: not permitted conflict with equal priority](../../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.md) ([`scenarios.astm.utm.ConflictEqualPriorityNotPermitted`](../../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.py))

## [Checked requirements](../../README.md#checked-requirements)
Expand All @@ -21,11 +22,16 @@
<th><a href="../../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="18" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td rowspan="19" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0005</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md">Nominal planning: conflict with higher priority</a><br><a href="../../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.md">Nominal planning: not permitted conflict with equal priority</a><br><a href="../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md">Validation of operational intents</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0300</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/dss_interoperability.md">ASTM F3548-21 UTM DSS interoperability</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">GEN0310</a></td>
<td>Implemented</td>
Expand Down
7 changes: 7 additions & 0 deletions monitoring/uss_qualifier/suites/astm/utm/f3548_21.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ name: ASTM F3548-21
resources:
flight_planners: resources.flight_planning.FlightPlannersResource
dss: resources.astm.f3548.v21.DSSInstanceResource
all_dss_instances: resources.astm.f3548.v21.DSSInstancesResource?
conflicting_flights: resources.flight_planning.FlightIntentsResource
priority_preemption_flights: resources.flight_planning.FlightIntentsResource
invalid_flight_intents: resources.flight_planning.FlightIntentsResource
nominal_planning_selector: resources.flight_planning.FlightPlannerCombinationSelectorResource?
priority_planning_selector: resources.flight_planning.FlightPlannerCombinationSelectorResource?
actions:
- test_scenario: # TODO confirm this should go here
scenario_type: scenarios.astm.utm.DSSInteroperability
resources:
primary_dss_instance: dss
all_dss_instances: all_dss_instances
on_failure: Continue
- action_generator:
generator_type: action_generators.flight_planning.FlightPlannerCombinations
resources:
Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/faa/uft/message_signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
<th><a href="../../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="18" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td rowspan="19" style="vertical-align:top;"><a href="../../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0005</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md">Nominal planning: conflict with higher priority</a><br><a href="../../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.md">Nominal planning: not permitted conflict with equal priority</a><br><a href="../../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md">Validation of operational intents</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">DSS0300</a></td>
<td>Implemented</td>
<td><a href="../../../scenarios/astm/utm/dss_interoperability.md">ASTM F3548-21 UTM DSS interoperability</a></td>
</tr>
<tr>
<td><a href="../../../requirements/astm/f3548/v21.md">GEN0310</a></td>
<td>Implemented</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: ASTM DSS tests
resources:
f3411v19_dss_instances: resources.astm.f3411.DSSInstancesResource
f3411v22a_dss_instances: resources.astm.f3411.DSSInstancesResource
f3548v21_dss_instances: resources.astm.f3548.v21.DSSInstancesResource
id_generator: resources.interuss.IDGeneratorResource
service_area: resources.netrid.ServiceAreaResource
actions:
Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/uspace/flight_auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
<th><a href="../README.md#checked-in">Checked in</a></th>
</tr>
<tr>
<td rowspan="18" style="vertical-align:top;"><a href="../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td rowspan="19" style="vertical-align:top;"><a href="../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td><a href="../../requirements/astm/f3548/v21.md">DSS0005</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md">Nominal planning: conflict with higher priority</a><br><a href="../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.md">Nominal planning: not permitted conflict with equal priority</a><br><a href="../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md">Validation of operational intents</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3548/v21.md">DSS0300</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/utm/dss_interoperability.md">ASTM F3548-21 UTM DSS interoperability</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3548/v21.md">GEN0310</a></td>
<td>Implemented</td>
Expand Down
7 changes: 6 additions & 1 deletion monitoring/uss_qualifier/suites/uspace/required_services.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,11 +388,16 @@
<td><a href="../../scenarios/astm/netrid/v22a/dss/isa_simple.md">ASTM NetRID DSS: Simple ISA</a></td>
</tr>
<tr>
<td rowspan="18" style="vertical-align:top;"><a href="../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td rowspan="19" style="vertical-align:top;"><a href="../../requirements/astm/f3548/v21.md">astm<br>.f3548<br>.v21</a></td>
<td><a href="../../requirements/astm/f3548/v21.md">DSS0005</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.md">Nominal planning: conflict with higher priority</a><br><a href="../../scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.md">Nominal planning: not permitted conflict with equal priority</a><br><a href="../../scenarios/astm/utm/flight_intent_validation/flight_intent_validation.md">Validation of operational intents</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3548/v21.md">DSS0300</a></td>
<td>Implemented</td>
<td><a href="../../scenarios/astm/utm/dss_interoperability.md">ASTM F3548-21 UTM DSS interoperability</a></td>
</tr>
<tr>
<td><a href="../../requirements/astm/f3548/v21.md">GEN0310</a></td>
<td>Implemented</td>
Expand Down

0 comments on commit 4b0dff0

Please sign in to comment.