Phase 1: in-memory ConnectionManager viewport fan-out, 500ms map debounce, cachetools TTLCache, background masscan/ffmpeg, compose memory caps. Phase 2: PostGIS geofences + ST_Intersects alerts, Timescale 1-min CAGGs and timestamp playback, FIRMS/WFIGS x firefighting ADS-B within 20 miles. No Redis/Kafka/Celery.
33 lines
1.1 KiB
Python
33 lines
1.1 KiB
Python
"""Phase 1 guardrails: compose limits, 500ms debounce, no extra brokers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
|
|
|
|
def test_compose_memory_limits_and_shared_buffers():
|
|
text = (ROOT / "docker-compose.yml").read_text()
|
|
assert "shared_buffers=2GB" in text
|
|
assert "shared_preload_libraries=timescaledb" in text
|
|
assert "memory: 3G" in text or "memory: 3GB" in text
|
|
assert "memory: 2G" in text or "memory: 2GB" in text
|
|
|
|
|
|
def test_map_moveend_debounced_500ms():
|
|
html = (ROOT / "app" / "static" / "index.html").read_text()
|
|
assert "map.on('moveend'" in html
|
|
# Existing 300ms debounce must be 500ms so pans don't spam bbox POSTs/WS.
|
|
assert "}, 500);" in html
|
|
assert "}, 300);" not in html.split("map.on('moveend'")[1][:800]
|
|
|
|
|
|
def test_no_redis_kafka_celery():
|
|
req = (ROOT / "app" / "requirements.txt").read_text().lower()
|
|
compose = (ROOT / "docker-compose.yml").read_text().lower()
|
|
for blob in (req, compose):
|
|
assert "redis" not in blob
|
|
assert "kafka" not in blob
|
|
assert "celery" not in blob
|
|
assert "cachetools" in req
|