Nexus-Grid / tests /test_spoof_engine.py
Abineshsdata's picture
OpenEnv Hackathon Final Submission
3e4c342
Raw
History Blame Contribute Delete
5.11 kB
"""
Test Spoof Engine — proves the spoof engine is deterministic given the same seed.
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from server.spoof_engine import SpoofEngine
class TestSpoofEngineDeterminism:
"""Verify that the spoof engine produces identical output for the same seed."""
def test_same_seed_same_packets(self):
"""Two engines with the same seed should produce identical packet logs."""
node_ids = [f"NODE_{i:02d}" for i in range(1, 21)]
engine1 = SpoofEngine(seed=42)
engine2 = SpoofEngine(seed=42)
logs1 = engine1.generate_packet_logs(node_ids, tick=0)
logs2 = engine2.generate_packet_logs(node_ids, tick=0)
assert len(logs1) == len(logs2)
for l1, l2 in zip(logs1, logs2):
assert l1["latency_ms"] == l2["latency_ms"], (
f"Latency mismatch: {l1['latency_ms']} != {l2['latency_ms']}"
)
assert l1["anomaly_flag"] == l2["anomaly_flag"]
def test_different_seed_different_packets(self):
"""Two engines with different seeds should produce different packet logs."""
node_ids = [f"NODE_{i:02d}" for i in range(1, 21)]
engine1 = SpoofEngine(seed=42)
engine2 = SpoofEngine(seed=123)
logs1 = engine1.generate_packet_logs(node_ids, tick=0)
logs2 = engine2.generate_packet_logs(node_ids, tick=0)
# At least some latencies should differ
diffs = sum(1 for l1, l2 in zip(logs1, logs2) if l1["latency_ms"] != l2["latency_ms"])
assert diffs > 0, "Different seeds should produce different packet logs"
class TestSpoofEngineAttacks:
"""Verify spoof engine attack mechanics."""
def test_phantom_injection_adds_mw(self):
"""Phantom injection should add extra MW to reported generation."""
engine = SpoofEngine(seed=42)
engine.configure_attack({
"type": "phantom_injection",
"target_node": "NODE_14",
"phantom_mw": 100.0,
"active": True,
})
ground_truth = {
"NODE_14": {"generation_mw": 400.0, "voltage_kv": 345.0, "frequency_hz": 60.0},
}
spoofed = engine.apply_spoofs(ground_truth, tick=0)
assert spoofed["NODE_14"]["generation_mw"] == 500.0 # 400 + 100
def test_quarantine_stops_spoofing(self):
"""After quarantine, node should not be spoofed."""
engine = SpoofEngine(seed=42)
engine.configure_attack({
"type": "phantom_injection",
"target_node": "NODE_14",
"phantom_mw": 100.0,
"active": True,
})
ground_truth = {
"NODE_14": {"generation_mw": 400.0, "voltage_kv": 345.0, "frequency_hz": 60.0},
}
# Before quarantine — spoofed
spoofed = engine.apply_spoofs(ground_truth, tick=0)
assert spoofed["NODE_14"]["generation_mw"] == 500.0
# After quarantine — should return truth
engine.quarantine_node("NODE_14")
spoofed = engine.apply_spoofs(ground_truth, tick=1)
assert spoofed["NODE_14"]["generation_mw"] == 400.0
def test_active_spoofs_list(self):
"""get_active_spoofs should return currently spoofed node IDs."""
engine = SpoofEngine(seed=42)
engine.configure_attack({
"type": "phantom_injection",
"target_node": "NODE_14",
"phantom_mw": 100.0,
"active": True,
})
assert "NODE_14" in engine.get_active_spoofs()
engine.quarantine_node("NODE_14")
assert "NODE_14" not in engine.get_active_spoofs()
def test_anomaly_flag_on_spoofed_nodes(self):
"""Spoofed nodes should show anomaly flags in packet logs."""
engine = SpoofEngine(seed=42)
engine.configure_attack({
"type": "phantom_injection",
"target_node": "NODE_14",
"phantom_mw": 100.0,
"active": True,
})
node_ids = [f"NODE_{i:02d}" for i in range(1, 21)]
# Generate logs for multiple ticks to build up consecutive high latency
for tick in range(3):
logs = engine.generate_packet_logs(node_ids, tick=tick)
# NODE_14 should have anomaly_flag set after 2+ ticks
node14_logs = [l for l in logs if l["source_node"] == "NODE_14"]
assert any(l["anomaly_flag"] for l in node14_logs), (
"NODE_14 should show anomaly flag after consecutive high-latency packets"
)
class TestSpoofEngineReset:
"""Verify reset behavior."""
def test_reset_clears_state(self):
"""Reset should clear all spoofs and quarantines."""
engine = SpoofEngine(seed=42)
engine.configure_attack({
"type": "phantom_injection",
"target_node": "NODE_14",
"phantom_mw": 100.0,
"active": True,
})
engine.quarantine_node("NODE_14")
engine.reset(seed=99)
assert engine.get_active_spoofs() == []
assert engine.get_quarantined() == []