v0.14.2: exempt global satellite telemetry from bbox filter (#108)

Bypass the v0.14.0 monitoring-area bbox filter for global-by-design satellite telemetry (sat_positions, sat_orbits). Recovers 462k+/87k+ dropped events; null-geom celestrak_tle + observer-anchored satpass_predict/n2yo_visualpasses untouched. Drift-detection test keeps the archive static set in sync with the adapter class attr.
This commit is contained in:
malice 2026-06-12 09:09:11 -06:00 committed by GitHub
commit ffb0e812cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 212 additions and 45 deletions

View file

@ -117,3 +117,30 @@ class TestProcessMessageMultiArea:
await c._process_message(_make_msg(_envelope("wzdx", -74.0, 40.7)), conn)
conn.execute.assert_awaited_once()
assert c._dropped == {}
class TestBypassBboxAdapters:
"""v0.14.2: _BYPASS_BBOX_ADAPTERS skip the bbox filter at archive time."""
@pytest.mark.asyncio
async def test_sat_positions_archived_when_out_of_bounds(self):
# ISS sub-sat point over NYC, only IDAHO configured -> normally dropped,
# but sat_positions is global-by-design so it bypasses and inserts.
c = ArchiveConsumer("nats://x", "postgresql://x")
c._monitoring_area = IDAHO
conn = AsyncMock()
await c._process_message(_make_msg(_envelope("sat_positions", -74.0, 40.7)), conn)
conn.execute.assert_awaited_once()
assert c._dropped == {}
assert c._bypassed == {"sat_positions": 1}
@pytest.mark.asyncio
async def test_tomtom_flow_still_dropped(self):
# Regression guard: a non-bypass adapter is still filtered out-of-bounds.
c = ArchiveConsumer("nats://x", "postgresql://x")
c._monitoring_area = IDAHO
conn = AsyncMock()
await c._process_message(_make_msg(_envelope("tomtom_flow", -74.0, 40.7)), conn)
conn.execute.assert_not_called()
assert c._dropped == {"tomtom_flow": 1}
assert c._bypassed == {}

View file

@ -0,0 +1,23 @@
"""v0.14.2 drift guard: the archive consumer mirrors the per-adapter
``bypass_bbox_filter`` flag as a static module-level set
(``archive._BYPASS_BBOX_ADAPTERS``) because the consumer reads events off the
wire and has no access to the adapter class at runtime. The two truth sources
must never diverge -- if someone adds a global-by-design adapter and sets
``bypass_bbox_filter = True`` but forgets the archive set (or vice versa), this
test fails at CI time.
"""
from central.adapter_discovery import discover_adapters
from central.archive import _BYPASS_BBOX_ADAPTERS
def test_archive_static_set_matches_adapter_class_attr():
bypass_from_classes = {
name
for name, cls in discover_adapters().items()
if getattr(cls, "bypass_bbox_filter", False)
}
assert bypass_from_classes == _BYPASS_BBOX_ADAPTERS, (
"archive._BYPASS_BBOX_ADAPTERS is out of sync with the adapter classes "
"that set bypass_bbox_filter=True. Update the set in central.archive to "
f"match: {sorted(bypass_from_classes)}"
)

View file

@ -32,6 +32,9 @@ def _ev(eid: str, geo: Geo) -> Event:
class _MockAdapter:
requires_api_key = None
enrichment_locations = ()
bypass_bbox_filter = False # v0.14.2: real adapters inherit this from
# SourceAdapter; the mock declares it so _run_adapter_loop's direct attr
# access works. Bypass tests use _BypassMockAdapter (overrides True).
def __init__(self, config, *_args) -> None:
self.config = config
@ -90,8 +93,8 @@ def sup_factory():
return _build
async def _drive(sup, events):
adapter = _MockAdapter(MagicMock(cadence_s=3600))
async def _drive(sup, events, adapter_cls=_MockAdapter):
adapter = adapter_cls(MagicMock(cadence_s=3600))
adapter.events = events
config = AdapterConfig(
name="mock", enabled=True, cadence_s=3600, settings={},
@ -187,3 +190,50 @@ async def test_refresh_loop_reloads_area_and_logs_summary(
assert any(
"publish bbox filter drop summary" in r.message for r in caplog.records
)
# --- v0.14.2: global-by-design satellite telemetry bypasses the bbox filter ---
class _BypassMockAdapter(_MockAdapter):
"""Stand-in for a global-by-design adapter (sat_positions/sat_orbits)."""
bypass_bbox_filter = True
class TestBypassBboxAdapters:
@pytest.mark.asyncio
async def test_sat_positions_publishes_when_out_of_bounds(self, sup_factory):
"""Centroid over NYC (outside Idaho) still publishes; not dropped."""
sup = sup_factory(IDAHO)
a = await _drive(
sup, [_ev("iss", Geo(centroid=NYC))], adapter_cls=_BypassMockAdapter
)
assert sup._publish_event.await_count == 1
assert a.published == {"iss"}
assert sup._dropped_publish == {}
assert sup._bypassed_publish == {"mock": 1}
@pytest.mark.asyncio
async def test_sat_orbits_publishes_when_linestring_outside_idaho(self, sup_factory):
"""An equatorial forward-track LineString never intersects Idaho, yet publishes."""
sup = sup_factory(IDAHO)
equator = Geo(geometry={
"type": "LineString",
"coordinates": [[0.0, 0.0], [10.0, 0.0], [20.0, 1.0]],
})
a = await _drive(
sup, [_ev("orbit1", equator)], adapter_cls=_BypassMockAdapter
)
assert sup._publish_event.await_count == 1
assert a.published == {"orbit1"}
assert sup._dropped_publish == {}
assert sup._bypassed_publish == {"mock": 1}
@pytest.mark.asyncio
async def test_tomtom_flow_still_drops_when_out_of_bounds(self, sup_factory):
"""Regression guard: a non-bypass adapter is still filtered (NYC drops)."""
sup = sup_factory(IDAHO)
a = await _drive(sup, [_ev("flow1", Geo(centroid=NYC))]) # _MockAdapter: bypass False
sup._publish_event.assert_not_called()
assert a.published == set()
assert sup._dropped_publish == {"mock": 1}
assert sup._bypassed_publish == {}