Files
rfcp/backend/tests/test_geometry/test_diffraction.py
mytec defa3ad440 @mytec: feat: Phase 3.0 Architecture Refactor
Major refactoring of RFCP backend:
- Modular propagation models (8 models)
- SharedMemoryManager for terrain data
- ProcessPoolExecutor parallel processing
- WebSocket progress streaming
- Building filtering pipeline (351k → 15k)
- 82 unit tests

Performance: Standard preset 38s → 5s (7.6x speedup)

Known issue: Detailed preset timeout (fix in 3.1.0)
2026-02-01 23:12:26 +02:00

61 lines
2.1 KiB
Python

"""
Unit tests for knife-edge diffraction calculations.
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
from app.geometry.diffraction import knife_edge_loss
def freq_to_wl(freq_mhz):
return 300.0 / freq_mhz
class TestKnifeEdgeLoss:
def test_no_obstruction_low_loss(self):
"""Negative h means clearance above LOS — loss should be small."""
loss = knife_edge_loss(d1_m=500, d2_m=500, h_m=-10, wavelength_m=freq_to_wl(1800))
assert loss >= 0
assert loss < 3
def test_grazing_obstruction(self):
"""h=0 means exactly at LOS line — ~6 dB loss."""
loss = knife_edge_loss(d1_m=500, d2_m=500, h_m=0, wavelength_m=freq_to_wl(1800))
assert 5 < loss < 8
def test_obstruction_increases_loss(self):
wl = freq_to_wl(1800)
loss_low = knife_edge_loss(d1_m=500, d2_m=500, h_m=1, wavelength_m=wl)
loss_high = knife_edge_loss(d1_m=500, d2_m=500, h_m=10, wavelength_m=wl)
assert loss_high > loss_low
def test_higher_freq_more_loss(self):
"""Higher frequency = shorter wavelength = more diffraction loss."""
loss_low_f = knife_edge_loss(d1_m=500, d2_m=500, h_m=5, wavelength_m=freq_to_wl(450))
loss_high_f = knife_edge_loss(d1_m=500, d2_m=500, h_m=5, wavelength_m=freq_to_wl(1800))
assert loss_high_f > loss_low_f
def test_zero_distance_safe(self):
"""Should not crash on zero distances."""
loss = knife_edge_loss(d1_m=0, d2_m=500, h_m=5, wavelength_m=freq_to_wl(900))
assert loss >= 0
def test_large_clearance(self):
"""Very deep clearance (large negative h) should have near-zero loss."""
loss = knife_edge_loss(d1_m=500, d2_m=500, h_m=-50, wavelength_m=freq_to_wl(900))
assert loss < 1.0
if __name__ == "__main__":
instance = TestKnifeEdgeLoss()
for method_name in [m for m in dir(instance) if m.startswith("test_")]:
try:
getattr(instance, method_name)()
print(f" PASS {method_name}")
except Exception as e:
print(f" FAIL {method_name}: {e}")
print("\nAll tests completed.")