mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-04-03 16:26:12 +00:00
- Introduced new test files for telemetry functionality, including integration, fuzzing, and extended tests to ensure robustness and performance. - Added tests for parsing LXMF display names and telemetry data, addressing potential bugs and ensuring correct handling of various input formats. - Implemented performance tests for the InterfacesPage component, validating rendering efficiency with a large number of discovered interfaces. - Enhanced existing tests for markdown rendering and link utilities to cover additional edge cases and improve stability.
100 lines
3.4 KiB
Python
100 lines
3.4 KiB
Python
from hypothesis import given, settings, strategies as st
|
|
from meshchatx.src.backend.telemetry_utils import Telemeter
|
|
|
|
# Strategies for telemetry data
|
|
st_lat_lon = st.floats(min_value=-90, max_value=90)
|
|
st_alt = st.floats(min_value=-10000, max_value=100000)
|
|
st_speed = st.floats(min_value=0, max_value=2000)
|
|
st_bearing = st.floats(min_value=0, max_value=360)
|
|
st_accuracy = st.floats(min_value=0, max_value=10000)
|
|
st_timestamp = st.integers(min_value=0, max_value=2**32 - 1)
|
|
|
|
|
|
@settings(deadline=None)
|
|
@given(
|
|
lat=st_lat_lon,
|
|
lon=st_lat_lon,
|
|
alt=st_alt,
|
|
speed=st_speed,
|
|
bearing=st_bearing,
|
|
acc=st_accuracy,
|
|
ts=st_timestamp,
|
|
)
|
|
def test_fuzz_pack_location(lat, lon, alt, speed, bearing, acc, ts):
|
|
packed = Telemeter.pack_location(lat, lon, alt, speed, bearing, acc, ts)
|
|
if packed is not None:
|
|
unpacked = Telemeter.unpack_location(packed)
|
|
if unpacked:
|
|
# Check for reasonable precision (we use 1e6 for lat/lon, 1e2 for others)
|
|
assert abs(unpacked["latitude"] - lat) < 0.000002
|
|
assert abs(unpacked["longitude"] - lon) < 0.000002
|
|
assert abs(unpacked["altitude"] - alt) < 0.02
|
|
assert abs(unpacked["speed"] - speed) < 0.02
|
|
assert abs(unpacked["bearing"] - bearing) < 0.02
|
|
assert abs(unpacked["accuracy"] - acc) < 0.02
|
|
assert unpacked["last_update"] == ts
|
|
|
|
|
|
@settings(deadline=None)
|
|
@given(
|
|
charge=st.integers(min_value=0, max_value=100),
|
|
charging=st.integers(min_value=0, max_value=1),
|
|
rssi=st.integers(min_value=-150, max_value=0),
|
|
snr=st.floats(min_value=-20, max_value=20),
|
|
q=st.integers(min_value=0, max_value=100),
|
|
)
|
|
def test_fuzz_full_telemetry_packing(charge, charging, rssi, snr, q):
|
|
battery = {"charge_percent": charge, "charging": charging}
|
|
physical_link = {"rssi": rssi, "snr": snr, "q": q}
|
|
|
|
packed = Telemeter.pack(battery=battery, physical_link=physical_link)
|
|
unpacked = Telemeter.from_packed(packed)
|
|
|
|
assert unpacked["battery"]["charge_percent"] == charge
|
|
assert unpacked["battery"]["charging"] == charging
|
|
assert unpacked["physical_link"]["rssi"] == rssi
|
|
assert abs(unpacked["physical_link"]["snr"] - snr) < 0.01
|
|
assert unpacked["physical_link"]["q"] == q
|
|
|
|
|
|
@settings(deadline=None)
|
|
@given(data=st.binary(min_size=0, max_size=2000))
|
|
def test_fuzz_from_packed_random_bytes(data):
|
|
# This should never crash
|
|
try:
|
|
Telemeter.from_packed(data)
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
@settings(deadline=None)
|
|
@given(
|
|
commands=st.lists(
|
|
st.dictionaries(
|
|
keys=st.one_of(st.integers(), st.text()),
|
|
values=st.one_of(st.integers(), st.text(), st.floats(), st.booleans()),
|
|
),
|
|
max_size=10,
|
|
)
|
|
)
|
|
def test_fuzz_command_parsing(commands):
|
|
# This simulates how commands are handled in meshchat.py
|
|
processed_commands = []
|
|
for cmd in commands:
|
|
new_cmd = {}
|
|
for k, v in cmd.items():
|
|
try:
|
|
if isinstance(k, str):
|
|
if k.startswith("0x"):
|
|
new_cmd[int(k, 16)] = v
|
|
else:
|
|
new_cmd[int(k)] = v
|
|
else:
|
|
new_cmd[k] = v
|
|
except (ValueError, TypeError):
|
|
new_cmd[k] = v
|
|
processed_commands.append(new_cmd)
|
|
|
|
# Just ensure no crash
|
|
assert len(processed_commands) == len(commands)
|