mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-05-08 18:34:58 +02:00
493 lines
17 KiB
Python
493 lines
17 KiB
Python
"""Tests for the compact OpenClaw query helpers.
|
|
|
|
These cover the new server-side lookup path so agents can avoid large
|
|
snapshot pulls for common questions.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture()
|
|
def sample_store():
|
|
from services.fetchers._store import latest_data, _data_lock
|
|
|
|
with _data_lock:
|
|
backup = {
|
|
"tracked_flights": list(latest_data.get("tracked_flights") or []),
|
|
"military_flights": list(latest_data.get("military_flights") or []),
|
|
"private_jets": list(latest_data.get("private_jets") or []),
|
|
"ships": list(latest_data.get("ships") or []),
|
|
"fishing_activity": list(latest_data.get("fishing_activity") or []),
|
|
"wastewater": list(latest_data.get("wastewater") or []),
|
|
"news": list(latest_data.get("news") or []),
|
|
"gdelt": list(latest_data.get("gdelt") or []),
|
|
"crowdthreat": list(latest_data.get("crowdthreat") or []),
|
|
"correlations": list(latest_data.get("correlations") or []),
|
|
"sar_anomalies": list(latest_data.get("sar_anomalies") or []),
|
|
"internet_outages": list(latest_data.get("internet_outages") or []),
|
|
"weather_alerts": list(latest_data.get("weather_alerts") or []),
|
|
"gps_jamming": list(latest_data.get("gps_jamming") or []),
|
|
"military_bases": list(latest_data.get("military_bases") or []),
|
|
}
|
|
latest_data["tracked_flights"] = [
|
|
{
|
|
"callsign": "AF1",
|
|
"registration": "82-8000",
|
|
"icao24": "adfdf8",
|
|
"alert_operator": "POTUS",
|
|
"type": "B744",
|
|
"lat": 38.95,
|
|
"lng": -77.45,
|
|
},
|
|
{
|
|
"callsign": "OXE2116",
|
|
"registration": "N36NE",
|
|
"icao24": "a0f011",
|
|
"operator": "Patriots",
|
|
"category": "Sports",
|
|
"type": "Boeing 767-323ER",
|
|
"intel_tags": "NFL, New England Patriots",
|
|
"lat": 39.24,
|
|
"lng": -96.96,
|
|
},
|
|
]
|
|
latest_data["military_flights"] = [
|
|
{
|
|
"callsign": "RCH123",
|
|
"registration": "03-3123",
|
|
"icao24": "abcd12",
|
|
"type": "C17",
|
|
"lat": 39.0,
|
|
"lng": -104.7,
|
|
}
|
|
]
|
|
latest_data["private_jets"] = [
|
|
{
|
|
"callsign": "EJA400",
|
|
"registration": "N400QS",
|
|
"icao24": "beef12",
|
|
"owner": "NetJets",
|
|
"type": "C68A",
|
|
"lat": 40.0,
|
|
"lng": -105.0,
|
|
}
|
|
]
|
|
latest_data["ships"] = [
|
|
{
|
|
"mmsi": "366999999",
|
|
"imo": "1234567",
|
|
"name": "BRAVO EUGENIA",
|
|
"shipType": "Yacht",
|
|
"yacht_owner": "Jerry Jones",
|
|
"yacht_name": "Bravo Eugenia",
|
|
"yacht_category": "Celebrity / Mogul",
|
|
"lat": 29.7,
|
|
"lng": -95.0,
|
|
}
|
|
]
|
|
latest_data["fishing_activity"] = [
|
|
{
|
|
"id": "gfw-event-1",
|
|
"name": "Fishing Event Alpha",
|
|
"lat": 12.3,
|
|
"lng": -45.6,
|
|
"flag": "PA",
|
|
}
|
|
]
|
|
latest_data["wastewater"] = [
|
|
{
|
|
"id": "ww-1",
|
|
"name": "Denver Wastewater Plant",
|
|
"lat": 39.73,
|
|
"lng": -104.99,
|
|
}
|
|
]
|
|
latest_data["news"] = [
|
|
{
|
|
"title": "Power outage reported near test facility",
|
|
"summary": "Grid instability around Denver area",
|
|
"source": "Example News",
|
|
"link": "https://example.invalid/story",
|
|
"lat": 39.74,
|
|
"lng": -104.99,
|
|
"risk_score": 0.7,
|
|
}
|
|
]
|
|
latest_data["gdelt"] = [
|
|
{
|
|
"properties": {
|
|
"title": "Military exercise escalates",
|
|
"sourceurl": "https://example.invalid/gdelt",
|
|
},
|
|
"geometry": {"coordinates": [-104.8, 39.1]},
|
|
}
|
|
]
|
|
latest_data["crowdthreat"] = [
|
|
{
|
|
"id": "ct-1",
|
|
"title": "Peaceful Protest Against Administration",
|
|
"summary": "Demonstration in Minnesota suburbs",
|
|
"category": "Protest",
|
|
"city": "Edina",
|
|
"state": "Minnesota",
|
|
"lat": 44.88,
|
|
"lng": -93.32,
|
|
}
|
|
]
|
|
latest_data["correlations"] = [
|
|
{
|
|
"type": "infra_cascade",
|
|
"severity": "medium",
|
|
"score": 60,
|
|
"drivers": ["Internet outage", "KiwiSDR offline"],
|
|
"lat": 38.97,
|
|
"lng": -77.43,
|
|
}
|
|
]
|
|
latest_data["sar_anomalies"] = [
|
|
{
|
|
"anomaly_id": "sar-1",
|
|
"kind": "new_object",
|
|
"magnitude": 0.8,
|
|
"lat": 38.96,
|
|
"lon": -77.44,
|
|
}
|
|
]
|
|
latest_data["internet_outages"] = [
|
|
{
|
|
"id": "outage-1",
|
|
"region": "Northern Virginia",
|
|
"severity": 55,
|
|
"lat": 38.98,
|
|
"lng": -77.42,
|
|
}
|
|
]
|
|
latest_data["weather_alerts"] = [
|
|
{
|
|
"id": "wx-1",
|
|
"event": "Severe Thunderstorm Warning",
|
|
"headline": "Storms near Washington",
|
|
"severity": "Severe",
|
|
"lat": 38.9,
|
|
"lng": -77.2,
|
|
}
|
|
]
|
|
latest_data["gps_jamming"] = [
|
|
{
|
|
"id": "gps-1",
|
|
"ratio": 0.8,
|
|
"lat": 38.92,
|
|
"lng": -77.3,
|
|
}
|
|
]
|
|
latest_data["military_bases"] = [
|
|
{
|
|
"id": "base-1",
|
|
"name": "Joint Base Andrews",
|
|
"lat": 38.81,
|
|
"lng": -76.87,
|
|
}
|
|
]
|
|
|
|
try:
|
|
yield
|
|
finally:
|
|
with _data_lock:
|
|
for key, value in backup.items():
|
|
latest_data[key] = value
|
|
|
|
|
|
def test_find_flights_returns_compact_matches(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 42)
|
|
result = telemetry.find_flights(callsign="AF1", limit=5)
|
|
|
|
assert result["version"] == 42
|
|
assert result["truncated"] is False
|
|
assert len(result["results"]) == 1
|
|
match = result["results"][0]
|
|
assert match["source_layer"] == "tracked_flights"
|
|
assert match["callsign"] == "AF1"
|
|
assert match["alert_operator"] == "POTUS"
|
|
|
|
|
|
def test_search_news_matches_news_and_gdelt(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 77)
|
|
result = telemetry.search_news(query="military", limit=10, include_gdelt=True)
|
|
|
|
assert result["version"] == 77
|
|
assert result["truncated"] is False
|
|
assert len(result["results"]) == 1
|
|
assert result["results"][0]["source_layer"] == "gdelt"
|
|
|
|
|
|
def test_search_news_matches_crowdthreat_events(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 78)
|
|
result = telemetry.search_news(query="minnesota protest", limit=10, include_gdelt=True)
|
|
|
|
assert result["version"] == 78
|
|
assert result["results"]
|
|
assert result["results"][0]["source_layer"] == "crowdthreat"
|
|
|
|
|
|
def test_get_layer_slice_short_circuits_when_version_is_unchanged(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 99)
|
|
result = telemetry.get_layer_slice(
|
|
layers=["tracked_flights", "ships"],
|
|
limit_per_layer=10,
|
|
since_version=99,
|
|
)
|
|
|
|
assert result["version"] == 99
|
|
assert result["changed"] is False
|
|
assert result["layers"] == {}
|
|
assert result["requested_layers"] == ["tracked_flights", "ships"]
|
|
|
|
|
|
def test_get_layer_slice_accepts_gfw_alias(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 101)
|
|
result = telemetry.get_layer_slice(
|
|
layers=["global_fishing_watch", "wastewater"],
|
|
limit_per_layer=10,
|
|
)
|
|
|
|
assert result["version"] == 101
|
|
assert result["requested_layers"] == ["fishing_activity", "wastewater"]
|
|
assert result["layers"]["fishing_activity"][0]["id"] == "gfw-event-1"
|
|
assert result["layers"]["wastewater"][0]["id"] == "ww-1"
|
|
|
|
|
|
def test_get_layer_slice_is_uncapped_when_limit_is_omitted(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
from services.fetchers._store import latest_data, _data_lock
|
|
|
|
with _data_lock:
|
|
latest_data["fishing_activity"] = [
|
|
{"id": "gfw-event-1", "lat": 12.3, "lng": -45.6},
|
|
{"id": "gfw-event-2", "lat": 12.4, "lng": -45.7},
|
|
]
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 111)
|
|
result = telemetry.get_layer_slice(layers=["fishing_activity"])
|
|
|
|
assert result["version"] == 111
|
|
assert len(result["layers"]["fishing_activity"]) == 2
|
|
assert result["truncated"] == {}
|
|
|
|
|
|
def test_get_telemetry_summary_includes_slow_layers(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 202)
|
|
result = telemetry.get_telemetry_summary()
|
|
|
|
assert result["version"] == 202
|
|
assert result["counts"]["fishing_activity"] == 1
|
|
assert result["counts"]["wastewater"] == 1
|
|
assert "fishing_activity" in result["available_layers"]
|
|
assert result["layer_aliases"]["global_fishing_watch"] == "fishing_activity"
|
|
|
|
|
|
def test_entities_near_finds_nearest_results(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 123)
|
|
result = telemetry.entities_near(
|
|
lat=39.0,
|
|
lng=-104.8,
|
|
radius_km=300,
|
|
entity_types=["military", "tracked"],
|
|
limit=10,
|
|
)
|
|
|
|
assert result["version"] == 123
|
|
assert result["results"]
|
|
assert result["results"][0]["source_layer"] in {"military_flights", "tracked_flights"}
|
|
assert result["results"][0]["distance_km"] <= 300
|
|
|
|
|
|
def test_find_ships_matches_yacht_owner_enrichment(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 124)
|
|
result = telemetry.find_ships(query="jerry jones", limit=10)
|
|
|
|
assert result["version"] == 124
|
|
assert result["results"]
|
|
match = result["results"][0]
|
|
assert match["name"] == "BRAVO EUGENIA"
|
|
assert match["owner"] == "Jerry Jones"
|
|
assert match["tracked_category"] == "Celebrity / Mogul"
|
|
|
|
|
|
def test_search_telemetry_searches_across_layers(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 125)
|
|
result = telemetry.search_telemetry(query="jerry jones", limit=10)
|
|
|
|
assert result["version"] == 125
|
|
assert result["results"]
|
|
assert result["results"][0]["source_layer"] == "ships"
|
|
assert result["results"][0]["label"] == "Bravo Eugenia"
|
|
|
|
|
|
def test_search_telemetry_finds_protests_without_layer_pull(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 126)
|
|
result = telemetry.search_telemetry(query="minnesota protest", limit=10)
|
|
|
|
assert result["version"] == 126
|
|
assert result["results"]
|
|
assert any(item["source_layer"] == "crowdthreat" for item in result["results"])
|
|
|
|
|
|
def test_search_telemetry_treats_generic_jet_term_as_aircraft_hint(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 127)
|
|
result = telemetry.search_telemetry(query="patriots jet", limit=10)
|
|
|
|
assert result["version"] == 127
|
|
assert result["results"]
|
|
top = result["results"][0]
|
|
assert top["source_layer"] == "tracked_flights"
|
|
assert top["group"] == "aircraft"
|
|
assert top["label"] == "OXE2116"
|
|
assert "patriots" in top["matched_tokens"]
|
|
assert result["groups"][0]["group"] == "aircraft"
|
|
|
|
|
|
def test_search_telemetry_still_returns_entity_when_query_has_extra_noise(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 128)
|
|
result = telemetry.search_telemetry(query="jerry jones diaper", limit=10)
|
|
|
|
assert result["version"] == 128
|
|
assert result["results"]
|
|
top = result["results"][0]
|
|
assert top["source_layer"] == "ships"
|
|
assert top["label"] == "Bravo Eugenia"
|
|
assert "jerry" in top["matched_tokens"]
|
|
assert "jones" in top["matched_tokens"]
|
|
|
|
|
|
def test_search_telemetry_handles_typos_with_cached_index(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 129)
|
|
result = telemetry.search_telemetry(query="patriats jet", limit=10)
|
|
|
|
assert result["version"] == 129
|
|
assert result["results"]
|
|
top = result["results"][0]
|
|
assert top["source_layer"] == "tracked_flights"
|
|
assert top["label"] == "OXE2116"
|
|
assert "patriots" in top["matched_tokens"]
|
|
|
|
|
|
def test_find_entity_prioritizes_aircraft_operator_and_callsign(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 130)
|
|
|
|
by_operator = telemetry.find_entity(query="patriots jet", limit=5)
|
|
assert by_operator["best_match"]["group"] == "aircraft"
|
|
assert by_operator["best_match"]["label"] == "OXE2116"
|
|
|
|
by_callsign = telemetry.find_entity(callsign="AF1", entity_type="aircraft", limit=5)
|
|
assert by_callsign["best_match"]["callsign"] == "AF1"
|
|
assert by_callsign["best_match"]["alert_operator"] == "POTUS"
|
|
|
|
|
|
def test_find_entity_prioritizes_maritime_owner_and_identifiers(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 131)
|
|
|
|
by_owner = telemetry.find_entity(query="jerry jones yacht", limit=5)
|
|
assert by_owner["best_match"]["group"] == "maritime"
|
|
assert by_owner["best_match"]["name"] == "BRAVO EUGENIA"
|
|
|
|
by_mmsi = telemetry.find_entity(mmsi="366999999", entity_type="ship", limit=5)
|
|
assert by_mmsi["best_match"]["mmsi"] == "366999999"
|
|
assert by_mmsi["best_match"]["owner"] == "Jerry Jones"
|
|
|
|
|
|
def test_openclaw_track_entity_creates_precise_aircraft_watch(sample_store, monkeypatch):
|
|
from services import openclaw_watchdog
|
|
from services.openclaw_channel import _dispatch_command
|
|
|
|
monkeypatch.setattr(openclaw_watchdog, "_ensure_running", lambda: None)
|
|
openclaw_watchdog.clear_watches()
|
|
try:
|
|
result = _dispatch_command("track_entity", {"query": "patriots jet"})
|
|
assert result["ok"] is True
|
|
data = result["data"]
|
|
assert data["watch_type"] == "track_aircraft"
|
|
assert data["watch"]["params"]["callsign"] == "OXE2116"
|
|
assert data["initial_lookup"]["best_match"]["group"] == "aircraft"
|
|
finally:
|
|
openclaw_watchdog.clear_watches()
|
|
|
|
|
|
def test_watchdog_aircraft_tracking_reads_split_flight_layers(sample_store):
|
|
from services.openclaw_watchdog import _check_track_aircraft, _check_track_callsign
|
|
from services.telemetry import get_cached_telemetry
|
|
|
|
fast = get_cached_telemetry()
|
|
by_callsign = _check_track_callsign({"callsign": "AF1"}, fast)
|
|
assert by_callsign is not None
|
|
assert by_callsign["data"]["source_layer"] == "tracked_flights"
|
|
|
|
by_owner = _check_track_aircraft({"owner": "patriots"}, fast)
|
|
assert by_owner is not None
|
|
assert by_owner["data"]["callsign"] == "OXE2116"
|
|
|
|
|
|
def test_correlate_entity_returns_evidence_pack_near_aircraft(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 132)
|
|
result = telemetry.correlate_entity(callsign="AF1", entity_type="aircraft", radius_km=80, limit=5)
|
|
|
|
assert result["version"] == 132
|
|
assert result["status"] == "context_found"
|
|
assert result["claim_level"] == "evidence_pack_not_verdict"
|
|
assert result["entity"]["callsign"] == "AF1"
|
|
signal_types = {signal["type"] for signal in result["signals"]}
|
|
assert "existing_correlation_near_entity" in signal_types
|
|
assert "sar_anomaly_near_entity" in signal_types
|
|
assert "infrastructure_disruption_near_entity" in signal_types
|
|
assert "environment_or_rf_hazard_near_entity" in signal_types
|
|
assert result["evidence"]["context_layers"]["correlations"][0]["type"] == "infra_cascade"
|
|
assert result["recommended_next"]
|
|
|
|
|
|
def test_openclaw_correlate_entity_command(sample_store, monkeypatch):
|
|
import services.telemetry as telemetry
|
|
from services.openclaw_channel import _dispatch_command
|
|
|
|
monkeypatch.setattr(telemetry, "get_data_version", lambda: 133)
|
|
result = _dispatch_command(
|
|
"correlate_entity",
|
|
{"entity_type": "ship", "mmsi": "366999999", "radius_km": 100},
|
|
)
|
|
|
|
assert result["ok"] is True
|
|
data = result["data"]
|
|
assert data["entity"]["mmsi"] == "366999999"
|
|
assert data["claim_level"] == "evidence_pack_not_verdict"
|
|
assert data["status"] in {"context_found", "no_nearby_context"}
|