Skip to content

Commit c04712b

Browse files
committed
Hard-restart SITL after mixed RX configuration
1 parent 44945e4 commit c04712b

1 file changed

Lines changed: 26 additions & 25 deletions

File tree

src/test/dualrx/dualrx_mixed_sitl_test.py

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -342,45 +342,46 @@ def configure_case(kind: str) -> list[str]:
342342
return commands
343343

344344

345-
def sitl_log_counts(sitl: SitlProcess) -> tuple[int, int]:
345+
def sitl_log_count(sitl: SitlProcess, marker: str) -> int:
346346
try:
347347
text = sitl.log_path.read_text(encoding="utf-8", errors="replace")
348348
except OSError:
349-
return 0, 0
350-
return text.count("[SYSTEM] Reset"), text.count("[SYSTEM] Init...")
349+
return 0
350+
return text.count(marker)
351351

352352

353-
def wait_for_sitl_reboot(
354-
sitl: SitlProcess,
355-
reset_count_before: int,
356-
init_count_before: int,
357-
timeout_s: float = 8.0,
358-
) -> None:
359-
"""Wait for CLI `save` to actually reset and finish re-execing SITL.
360-
361-
Waiting for the TCP port alone is insufficient: the pre-reset listener can
362-
still accept a client while the delayed CLI reboot is pending, after which
363-
systemReset() closes that just-opened MSP connection underneath the test.
364-
"""
353+
def wait_for_sitl_reset(sitl: SitlProcess, reset_count_before: int, timeout_s: float = 8.0) -> None:
354+
"""Wait until CLI `save` has persisted configuration and entered reset."""
365355
deadline = time.monotonic() + timeout_s
366-
saw_reset = False
367356
last_reset_count = reset_count_before
368-
last_init_count = init_count_before
369357
while time.monotonic() < deadline:
370358
sitl.check_alive()
371-
last_reset_count, last_init_count = sitl_log_counts(sitl)
359+
last_reset_count = sitl_log_count(sitl, "[SYSTEM] Reset")
372360
if last_reset_count > reset_count_before:
373-
saw_reset = True
374-
if saw_reset and last_init_count > init_count_before:
375361
return
376362
time.sleep(0.02)
377363
raise TestFailure(
378-
"SITL did not complete CLI save/reboot cycle within "
379-
f"{timeout_s:.1f}s (reset {reset_count_before}->{last_reset_count}, "
380-
f"init {init_count_before}->{last_init_count})\n{sitl.tail_log(lines=80)}"
364+
"SITL did not enter CLI save/reset cycle within "
365+
f"{timeout_s:.1f}s (reset {reset_count_before}->{last_reset_count})\n"
366+
f"{sitl.tail_log(lines=80)}"
381367
)
382368

383369

370+
def hard_restart_sitl_after_configuration(sitl: SitlProcess, reset_count_before: int) -> None:
371+
"""Replace SITL's in-process exec reboot with a clean harness restart.
372+
373+
The mixed serial layout opens UARTs lazily. During the exec-based reboot a
374+
TCP listener can survive long enough for the new instance to hit EADDRINUSE,
375+
leaving a receiver connected to the dying listener. Once `save` has reached
376+
systemReset(), terminate that process completely and start a fresh one from
377+
the saved EEPROM so every UART listener is recreated from a clean process.
378+
"""
379+
wait_for_sitl_reset(sitl, reset_count_before)
380+
sitl.stop()
381+
time.sleep(0.05)
382+
sitl.start()
383+
384+
384385
def run_case(kind: str, binary: Path, repo: Path, tcp_base: int, temp_dir: Path) -> None:
385386
eeprom = temp_dir / f"{kind}.bin"
386387
log_path = temp_dir / f"{kind}.log"
@@ -393,9 +394,9 @@ def run_case(kind: str, binary: Path, repo: Path, tcp_base: int, temp_dir: Path)
393394
msp_port = tcp_port(tcp_base, UART_MSP)
394395
wait_tcp("127.0.0.1", msp_port, 8.0, sitl)
395396
time.sleep(0.15)
396-
reset_count, init_count = sitl_log_counts(sitl)
397+
reset_count = sitl_log_count(sitl, "[SYSTEM] Reset")
397398
configure_cli("127.0.0.1", msp_port, configure_case(kind))
398-
wait_for_sitl_reboot(sitl, reset_count, init_count)
399+
hard_restart_sitl_after_configuration(sitl, reset_count)
399400
wait_tcp("127.0.0.1", msp_port, 8.0, sitl)
400401

401402
msp = MspClient("127.0.0.1", msp_port, timeout_s=2.0)

0 commit comments

Comments
 (0)