Vibe coded some untrustworthy test scripts

This commit is contained in:
Your Name
2026-07-31 14:06:13 +03:00
parent 4328a76e29
commit 738982ba0e
3 changed files with 871 additions and 0 deletions
+263
View File
@@ -0,0 +1,263 @@
#!/usr/bin/env python3
import serial
import threading
import time
# ==========================
# Configuration
# ==========================
PORT = "/dev/ttyACM0"
BAUDRATE = 115200
COMMAND_PREFIX = 0x69
COMMAND_ACK = 0
COMMAND_NACK = 1
LED = 2
DEVICE_ID = 0
# Test parameters
TEST_DURATION = 2.0 # seconds per stage
LOSS_THRESHOLD = 1.0 # percent
# Rates to test (packets/second)
RATES = [
100,
200,
500,
1000,
2000,
4000,
8000,
16000,
]
# ==========================
# Statistics
# ==========================
lock = threading.Lock()
tx_packets = 0
tx_bytes = 0
rx_packets = 0
rx_ack = 0
rx_nack = 0
rx_error = 0
# ==========================
# Packet helpers
# ==========================
def calculate_crc(msg: bytes) -> int:
s = sum(msg) & 0xFF
return (-s) & 0xFF
def make_packet(command: int, data: bytes = b"") -> bytes:
pkt = bytearray()
pkt.append(COMMAND_PREFIX)
pkt.append(len(data))
pkt.append(DEVICE_ID)
pkt.append(command)
pkt.append(0)
pkt.extend(data)
pkt[4] = calculate_crc(pkt[:4] + pkt[5:])
return bytes(pkt)
def verify_crc(packet: bytes) -> bool:
crc = packet[4]
calc = calculate_crc(packet[:4] + packet[5:])
return crc == calc
def packet_size(buf: bytes):
if len(buf) < 2:
return None
return 5 + buf[1]
# ==========================
# Receiver
# ==========================
def reader(ser):
global rx_packets, rx_ack, rx_nack, rx_error
rx = bytearray()
while True:
data = ser.read(4096)
if not data:
continue
rx.extend(data)
while True:
if not rx:
break
# ASCII log output
if rx[0] != COMMAND_PREFIX:
nl = rx.find(b"\n")
if nl == -1:
rx.clear()
break
line = rx[: nl + 1]
del rx[: nl + 1]
try:
print("[LOG]", line.decode().rstrip())
except UnicodeDecodeError:
pass
continue
size = packet_size(rx)
if size is None or len(rx) < size:
break
pkt = bytes(rx[:size])
del rx[:size]
if not verify_crc(pkt):
continue
cmd = pkt[3]
with lock:
rx_packets += 1
if cmd == COMMAND_ACK:
rx_ack += 1
elif cmd == COMMAND_NACK:
rx_nack += 1
elif cmd == COMMAND_ERROR:
rx_error += 1
# ==========================
# Benchmark
# ==========================
def run_stage(ser, packet, target_pps):
global tx_packets, tx_bytes
global rx_packets, rx_ack, rx_nack, rx_error
with lock:
tx_packets = 0
tx_bytes = 0
rx_packets = 0
rx_ack = 0
rx_nack = 0
rx_error = 0
interval = 1.0 / target_pps
start = time.perf_counter()
end = start + TEST_DURATION
next_tx = start
while True:
now = time.perf_counter()
if now >= end:
break
if now >= next_tx:
ser.write(packet)
with lock:
tx_packets += 1
tx_bytes += len(packet)
next_tx += interval
else:
sleep = next_tx - now
if sleep > 0:
time.sleep(min(sleep, 0.0005))
# Allow final ACKs to arrive
time.sleep(0.25)
elapsed = time.perf_counter() - start
with lock:
tx = tx_packets
ack = rx_ack
nack = rx_nack
err = rx_error
bytes_sent = tx_bytes
loss = 0.0
if tx:
loss = (tx - ack) / tx * 100.0
print()
print("=" * 60)
print(f"Target Rate : {target_pps:>7} pkt/s")
print(f"Elapsed : {elapsed:.3f} s")
print(f"Sent : {tx}")
print(f"ACK : {ack}")
print(f"NACK : {nack}")
print(f"ERROR : {err}")
print(f"Loss : {loss:.2f}%")
print(f"Actual TX : {tx / elapsed:.0f} pkt/s")
print(f"Throughput : {bytes_sent / elapsed / 1024:.2f} KiB/s")
return loss
# ==========================
# Main
# ==========================
def main():
packet = make_packet(LED)
print(f"Opening {PORT} @ {BAUDRATE} baud...")
ser = serial.Serial(PORT, BAUDRATE, timeout=0.01)
threading.Thread(target=reader, args=(ser,), daemon=True).start()
print("\nStarting communication benchmark...\n")
previous_rate = None
for rate in RATES:
loss = run_stage(ser, packet, rate)
if loss > LOSS_THRESHOLD:
print()
print(
f"Link became unreliable (> {LOSS_THRESHOLD:.1f}% loss)."
)
if previous_rate is not None:
print(f"Maximum reliable rate ≈ {previous_rate} pkt/s")
break
previous_rate = rate
else:
print()
print("Completed all test stages.")
print(f"Reliable up to at least {RATES[-1]} pkt/s.")
ser.close()
if __name__ == "__main__":
main()