Skip to content

Commit

Permalink
[uss_qualifier] DSS0030 slight overlap subscription interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Shastick committed Nov 27, 2023
1 parent 3295d62 commit 2abe74a
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ def __init__(
# sub id is isa_id with last character replaced with '1'
# (the generated isa_id ends with a few '0's)
self._sub_id = self._isa_id[:-1] + "1"
self._slight_overlap_sub_id = self._isa_id[:-1] + "2"
self._isa_version: Optional[str] = None
self._isa = isa.specification

now = arrow.utcnow().datetime
self._isa_start_time = self._isa.shifted_time_start(now)
self._isa_end_time = self._isa.shifted_time_end(now)
self._isa_area = [vertex.as_s2sphere() for vertex in self._isa.footprint]
self._slight_overlap_area = utils.generate_slight_overlap_area(self._isa_area)

def run(self, context: ExecutionContext):
self.begin_test_scenario(context)
Expand Down Expand Up @@ -191,6 +193,41 @@ def _check_subscription_behaviors(self):
query_timestamps=[created_subscription.query.request.timestamp],
)

# Create a subscription to the ISA that only barely overlaps with it:
with self.check(
"Create a subscription within the ISA footprint", [self._dss.participant_id]
) as check:
slight_overlap_subscription = self._dss_wrapper.put_sub(
check=check,
area_vertices=self._slight_overlap_area,
alt_lo=self._isa.altitude_min,
alt_hi=self._isa.altitude_max,
start_time=self._isa_start_time,
end_time=self._isa_end_time,
uss_base_url=self._isa.base_url,
sub_id=self._slight_overlap_sub_id,
sub_version=None,
)

# Check the subscription
with self.check(
"Subscription that only barely overlaps the ISA contains the ISA",
[self._dss.participant_id],
) as check:
if created_isa.dss_query.isa.id not in [
isa.id for isa in slight_overlap_subscription.isas
]:
check.record_failed(
summary="Subscription response does not include the freshly created ISA",
severity=Severity.High,
participants=[self._dss.participant_id],
details=f"The subscription created for the area {self._isa_area} is expected to contain the ISA created for this same area. The returned subscription did not mention it.",
query_timestamps=[
created_isa.dss_query.query.request.timestamp,
created_subscription.query.request.timestamp,
],
)

# Delete the ISA
with self.check(
"Delete the ISA",
Expand Down Expand Up @@ -304,6 +341,9 @@ def _delete_isa_if_exists(self):

def _clean_any_sub(self):
self._dss_wrapper.cleanup_subs_in_area(self._isa_area)
# Explicitly clean up in the separate area in case the DSS does
# not return that subscription when searching in the ISA's footpring
self._dss_wrapper.cleanup_subs_in_area(self._slight_overlap_area)

def cleanup(self):
self.begin_cleanup()
Expand Down
41 changes: 38 additions & 3 deletions monitoring/uss_qualifier/scenarios/astm/netrid/common/dss/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from typing import Optional, List

from s2sphere import LatLng

from monitoring.monitorlib.fetch import rid as fetch
from monitoring.monitorlib.geo import LatLngPoint
from monitoring.monitorlib.mutate import rid as mutate
from monitoring.monitorlib.infrastructure import UTMClientSession
from monitoring.monitorlib.mutate import rid as mutate
from monitoring.monitorlib.rid import RIDVersion
from monitoring.uss_qualifier.common_data_definitions import Severity
from monitoring.uss_qualifier.scenarios.astm.netrid.dss_wrapper import DSSWrapper
from monitoring.uss_qualifier.scenarios.scenario import GenericTestScenario


Expand Down Expand Up @@ -67,3 +67,38 @@ def delete_isa_if_exists(
f"Attempting to notify subscriber for ISA {isa_id} at {subscriber_url} resulted in {notification.status_code}",
query_timestamps=[notification.query.request.timestamp],
)


def generate_slight_overlap_area(in_points: List[LatLng]) -> List[LatLng]:
"""
Takes a list of LatLng points and returns a list of LatLng points that represents
a polygon only slightly overlapping with the input, and that is roughly half the diameter of the input.
The returned polygon is built from the first point of the input, from which a square
is drawn in the direction opposite of the center of the input polygon.
"""
overlap_corner = in_points[0] # the spot that will have a tiny overlap

# Compute the center of mass of the input polygon
center = LatLng.from_degrees(
sum([point.lat().degrees for point in in_points]) / len(in_points),
sum([point.lng().degrees for point in in_points]) / len(in_points),
)

delta_lat = center.lat().degrees - overlap_corner.lat().degrees
delta_lng = center.lng().degrees - overlap_corner.lng().degrees

same_lat_point = LatLng.from_degrees(
overlap_corner.lat().degrees, overlap_corner.lng().degrees - delta_lng
)
same_lng_point = LatLng.from_degrees(
overlap_corner.lat().degrees - delta_lat, overlap_corner.lng().degrees
)

opposite_corner = LatLng.from_degrees(
overlap_corner.lat().degrees - delta_lat,
overlap_corner.lng().degrees - delta_lng,
)

return [overlap_corner, same_lat_point, opposite_corner, same_lng_point]
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import List, Tuple

from s2sphere import LatLng

from .utils import generate_slight_overlap_area


def _points(in_points: List[Tuple[float, float]]) -> List[LatLng]:
return [LatLng.from_degrees(*p) for p in in_points]


def test_generate_slight_overlap_area():
# Square around 0,0 of edge length 2 -> first corner at 1,1 -> expect a square with overlapping corner at 1,1
assert generate_slight_overlap_area(
_points([(1, 1), (1, -1), (-1, -1), (-1, 1)])
) == _points([(1, 1), (1, 2), (2, 2), (2, 1)])

# Square with diagonal from 0,0 to 1,1 -> first corner at 1,1 -> expect a square with overlapping corner at 1,1
assert generate_slight_overlap_area(
_points([(1, 1), (0, 1), (0, 0), (1, 0)])
) == _points([(1, 1), (1, 1.5), (1.5, 1.5), (1.5, 1)])

# Square with diagonal from 0,0 to -1,-1 -> first corner at -1,-1 -> expect a square with overlapping corner at -1,-1
assert generate_slight_overlap_area(
_points([(-1, -1), (0, -1), (0, 0), (-1, 0)])
) == _points([(-1, -1), (-1, -1.5), (-1.5, -1.5), (-1.5, -1)])

# Square with diagonal from 0,0 to -1,1 -> first corner at -1,1 -> expect a square with overlapping corner at -1,0
assert generate_slight_overlap_area(
_points([(-1, 1), (-1, 0), (0, 0), (0, 1)])
) == _points([(-1, 1), (-1, 1.5), (-1.5, 1.5), (-1.5, 1)])

# Square with diagonal from 0,0 to 1,-1 -> first corner at 1,-1 -> expect a square with overlapping corner at 1,-1
assert generate_slight_overlap_area(
_points([(1, -1), (1, 0), (0, 0), (0, -1)])
) == _points([(1, -1), (1, -1.5), (1.5, -1.5), (1.5, -1)])
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ and return the up-to-date subscription in the response to the query mutating the

Failure to do so means that the DSS is not properly implementing **[astm.f3411.v19.DSS0030,a](../../../../../requirements/astm/f3411/v19.md)**.

#### Subscription that only barely overlaps the ISA contains the ISA check

A subscription that is created for a volume that only barely overlaps with the previously created ISA should still
contain the ISA in the reply from the server, otherwise the DSS does not comply with **[astm.f3411.v19.DSS0030,c](../../../../../requirements/astm/f3411/v19.md)**

#### Delete the ISA check

If that ISA cannot be deleted, the **[astm.f3411.v19.DSS0030,d](../../../../../requirements/astm/f3411/v19.md)** requirement to implement the ISA deletion endpoint might not be met.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ and return the up-to-date subscription in the response to the query mutating the

Failure to do so means that the DSS is not properly implementing **[astm.f3411.v22a.DSS0030,a](../../../../../requirements/astm/f3411/v22a.md)**.

#### Subscription that only barely overlaps the ISA contains the ISA check

A subscription that is created for a volume that only barely overlaps with the previously created ISA should still
contain the ISA in the reply from the server, otherwise the DSS does not comply with **[astm.f3411.v22a.DSS0030,c](../../../../../requirements/astm/f3411/v22a.md)**

#### Delete the ISA check

If that ISA cannot be deleted, the **[astm.f3411.v22a.DSS0030,d](../../../../../requirements/astm/f3411/v22a.md)** requirement to implement the ISA deletion endpoint might not be met.
Expand Down

0 comments on commit 2abe74a

Please sign in to comment.