#!/usr/bin/env python3 # -*- coding: utf-8 -*- """E6 24h soak driver (U15 mismatch frequency, self-heal design anchor E6). Protocol (docs/网络/网络自愈架构设计.md §4.8, anchor §5.2 E6): 24h normal operation + periodic E1 stress injection: - every hour : relisten_stress :7003 n=10 gap=100 (UI-like churn) - every 4th hour : full E1 (:7003 n=50 gap=0 + :21 n=50 gap=100) Device-side confirmed hits are counted by the NET_U15_PROBE firmware and appear in the serial log as "U15 probe: sockN rx=... hits=N" (first hit immediately, then <=1/hour). Read the verdict from serial.log afterwards. Usage: python e6_soak.py [--hours 24] Exit: 0 = soak completed; nonzero = driver error (device untouched). """ import argparse import os import subprocess import sys import time ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) STRESS = os.path.join(ROOT, "test", "host", "relisten_stress.py") def log(msg): print("[%s] %s" % (time.strftime("%m-%d %H:%M:%S"), msg), flush=True) def burst(args_list, tag): t0 = time.time() try: r = subprocess.run([sys.executable, STRESS] + args_list, capture_output=True, text=True, timeout=900) out = (r.stdout or "") + (r.stderr or "") tail = [ln for ln in out.splitlines() if "ok=" in ln or "latency" in ln] dt = time.time() - t0 log("%s rc=%d %.0fs %s" % (tag, r.returncode, dt, " | ".join(tail[-2:]))) except Exception as e: # driver hiccup must not abort the soak log("%s ERROR %r" % (tag, e)) def main(): ap = argparse.ArgumentParser() ap.add_argument("--hours", type=int, default=24) a = ap.parse_args() log("E6 soak start: %d h, hourly :7003x10, every-4h E1 full" % a.hours) t_start = time.time() for h in range(1, a.hours + 1): # sleep first: hour boundary cadence remain = t_start + h * 3600.0 - time.time() if remain > 0: time.sleep(remain) burst(["--port", "7003", "--n", "10", "--gap-ms", "100"], "hour%02d :7003x10" % h) if h % 4 == 0: burst(["--port", "7003", "--n", "50", "--gap-ms", "0"], "hour%02d E1 :7003x50g0" % h) burst(["--port", "21", "--n", "50", "--gap-ms", "100"], "hour%02d E1 :21x50g100" % h) log("E6 soak done: %.1f h elapsed" % ((time.time() - t_start) / 3600.0)) return 0 if __name__ == "__main__": sys.exit(main())