Skip to content
24 changes: 0 additions & 24 deletions .basedpyright/baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -18361,22 +18361,6 @@
}
],
"./monitoring/uss_qualifier/scenarios/astm/utm/nominal_planning/conflict_equal_priority_not_permitted/conflict_equal_priority_not_permitted.py": [
{
"code": "reportAttributeAccessIssue",
"range": {
"startColumn": 15,
"endColumn": 28,
"lineCount": 1
}
},
{
"code": "reportAttributeAccessIssue",
"range": {
"startColumn": 23,
"endColumn": 35,
"lineCount": 1
}
},
{
"code": "reportArgumentType",
"range": {
Expand Down Expand Up @@ -18533,14 +18517,6 @@
}
],
"./monitoring/uss_qualifier/scenarios/astm/utm/nominal_planning/conflict_higher_priority/conflict_higher_priority.py": [
{
"code": "reportAttributeAccessIssue",
"range": {
"startColumn": 23,
"endColumn": 35,
"lineCount": 1
}
},
{
"code": "reportArgumentType",
"range": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
Scope,
)

from monitoring.monitorlib.clients.flight_planning.client import (
FlightPlannerClient,
)
from monitoring.monitorlib.clients.flight_planning.flight_info import (
AirspaceUsageState,
FlightInfo,
UasState,
)
from monitoring.monitorlib.clients.flight_planning.flight_info_template import (
Expand All @@ -18,22 +14,16 @@
FlightPlanStatus,
PlanningActivityResult,
)
from monitoring.uss_qualifier.resources.astm.f3548.v21 import DSSInstanceResource
from monitoring.uss_qualifier.resources.astm.f3548.v21.dss import DSSInstance
from monitoring.uss_qualifier.resources.astm.f3548.v21.dss import DSSInstanceResource
from monitoring.uss_qualifier.resources.flight_planning import FlightIntentsResource
from monitoring.uss_qualifier.resources.flight_planning.flight_intent import (
FlightIntentID,
)
from monitoring.uss_qualifier.resources.flight_planning.flight_intent_validation import (
ExpectedFlightIntent,
estimate_scenario_execution_max_extents,
validate_flight_intent_templates,
)
from monitoring.uss_qualifier.resources.flight_planning.flight_planners import (
FlightPlannerResource,
)
from monitoring.uss_qualifier.scenarios.astm.utm.clear_area_validation import (
validate_clear_area,
from monitoring.uss_qualifier.scenarios.astm.utm.nominal_planning.planning_sequence_scenario import (
PlanningSequenceScenario,
)
from monitoring.uss_qualifier.scenarios.astm.utm.test_steps import OpIntentValidator
from monitoring.uss_qualifier.scenarios.flight_planning.prioritization_test_steps import (
Expand All @@ -44,19 +34,17 @@
)
from monitoring.uss_qualifier.scenarios.flight_planning.test_steps import (
activate_flight,
cleanup_flights,
delete_flight,
plan_flight,
submit_flight,
)
from monitoring.uss_qualifier.scenarios.scenario import (
ScenarioCannotContinueError,
TestScenario,
)
from monitoring.uss_qualifier.suites.suite import ExecutionContext


class ConflictEqualPriorityNotPermitted(TestScenario):
class ConflictEqualPriorityNotPermitted(PlanningSequenceScenario):
flight1_id: str | None = None
flight1_planned: FlightInfoTemplate
flight1_activated: FlightInfoTemplate
Expand All @@ -65,27 +53,18 @@ class ConflictEqualPriorityNotPermitted(TestScenario):
flight1c_activated: FlightInfoTemplate

flight2_id: str | None = None
flight2m_planned: FlightInfoTemplate
flight2_planned: FlightInfoTemplate
flight2_activated: FlightInfoTemplate
flight2_nonconforming: FlightInfoTemplate

tested_uss: FlightPlannerClient
control_uss: FlightPlannerClient
dss: DSSInstance
flight_intents_templates: dict[FlightIntentID, FlightInfoTemplate]
equal_prio_flight2m_planned: FlightInfoTemplate
equal_prio_flight2_planned: FlightInfoTemplate
equal_prio_flight2_activated: FlightInfoTemplate
equal_prio_flight2_nonconforming: FlightInfoTemplate

def __init__(
self,
tested_uss: FlightPlannerResource,
control_uss: FlightPlannerResource,
dss: DSSInstanceResource,
flight_intents: FlightIntentsResource | None = None,
flight_intents: FlightIntentsResource,
):
super().__init__()
self.tested_uss = tested_uss.client
self.control_uss = control_uss.client

scopes = {
Scope.StrategicCoordination: "search for operational intent references to verify outcomes of planning activities and retrieve operational intent details"
}
Expand All @@ -94,8 +73,6 @@ def __init__(
"query for telemetry for off-nominal operational intents"
)

self.dss = dss.get_instance(scopes)

expected_flight_intents = [
ExpectedFlightIntent(
"flight1_planned",
Expand Down Expand Up @@ -164,54 +141,16 @@ def __init__(
), # Note: this intent expected to produce Nonconforming state, but this is hard to verify without telemetry. UAS state is not actually off-nominal.
]

self.flight_intents_templates = (
flight_intents.get_flight_intents() if flight_intents else {}
super().__init__(
flight_intents=flight_intents,
expected_flight_intents=expected_flight_intents,
tested_uss=tested_uss,
control_uss=control_uss,
dss=dss,
scopes=scopes,
)
try:
validate_flight_intent_templates(
self.flight_intents_templates, expected_flight_intents
)
except ValueError as e:
raise ValueError(
f"`{self.me()}` TestScenario requirements for flight_intents not met: {e}"
)

for efi in expected_flight_intents:
setattr(
self,
efi.intent_id.replace("equal_prio_", ""),
self.flight_intents_templates[efi.intent_id],
)

def resolve_flight(self, flight_template: FlightInfoTemplate) -> FlightInfo:
return flight_template.resolve(self.time_context.evaluate_now())

def run(self, context: ExecutionContext):
self.begin_test_scenario(context)

self.record_note(
"Tested USS",
f"{self.tested_uss.participant_id}",
)
self.record_note(
"Control USS",
f"{self.control_uss.participant_id}",
)

self.begin_test_case("Prerequisites check")
self.begin_test_step("Verify area is clear")
estimated_max_extents = estimate_scenario_execution_max_extents(
self.time_context, self.flight_intents_templates
)
validate_clear_area(
self,
self.dss,
[estimated_max_extents],
ignore_self=False,
)
self.end_test_step()
self.end_test_case()

def run_planning_sequence(self, context: ExecutionContext):
self.begin_test_case("Attempt to plan flight into conflict")
self._attempt_plan_flight_conflict()
self.end_test_case()
Expand All @@ -234,11 +173,9 @@ def run(self, context: ExecutionContext):
self._modify_activated_flight_preexisting_conflict(flight_1_oi_ref)
self.end_test_case()

self.end_test_scenario()

def _attempt_plan_flight_conflict(self):
self.begin_test_step("Plan Flight 2")
flight2_planned = self.resolve_flight(self.flight2_planned)
flight2_planned = self.resolve_flight(self.equal_prio_flight2_planned)

with OpIntentValidator(
self,
Expand All @@ -257,7 +194,7 @@ def _attempt_plan_flight_conflict(self):
self.end_test_step()

self.begin_test_step("Activate Flight 2")
flight2_activated = self.resolve_flight(self.flight2_activated)
flight2_activated = self.resolve_flight(self.equal_prio_flight2_activated)

with OpIntentValidator(
self,
Expand Down Expand Up @@ -448,7 +385,7 @@ def _modify_activated_flight_preexisting_conflict(
self.end_test_step()

self.begin_test_step("Plan Flight 2m")
flight2m_planned = self.resolve_flight(self.flight2m_planned)
flight2m_planned = self.resolve_flight(self.equal_prio_flight2m_planned)

with OpIntentValidator(
self,
Expand All @@ -468,7 +405,9 @@ def _modify_activated_flight_preexisting_conflict(
self.end_test_step()

self.begin_test_step("Declare Flight 2 non-conforming")
flight2_nonconforming = self.resolve_flight(self.flight2_nonconforming)
flight2_nonconforming = self.resolve_flight(
self.equal_prio_flight2_nonconforming
)

with OpIntentValidator(
self,
Expand Down Expand Up @@ -536,8 +475,3 @@ def _modify_activated_flight_preexisting_conflict(
}:
validator.expect_not_shared()
self.end_test_step()

def cleanup(self):
self.begin_cleanup()
cleanup_flights(self, (self.control_uss, self.tested_uss))
self.end_cleanup()
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ FlightPlannerResource that will manage conflicting Flight 2.
### dss
DSSInstanceResource that provides access to a DSS instance where flight creation/sharing can be verified.

## Prerequisites check test case

### [Verify area is clear test step](../../clear_area_validation.md)

While this scenario assumes that the area used is already clear of any pre-existing flights (using, for instance, PrepareFlightPlanners scenario) in order to avoid a large number of area-clearing operations, the scenario will not proceed correctly if the area was left in a dirty state following a previous scenario that was supposed to leave the area clear. This test step verifies that the area is clear.

## Attempt to plan flight in conflict test case
![Test case summary illustration](assets/attempt_to_plan_flight_into_conflict.svg)

Expand Down
Loading
Loading