Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions dimos/core/test_native_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
The echo script writes received CLI args to a temp file for assertions.
"""

from collections.abc import Generator
import json
from pathlib import Path
import threading
import time

import pytest
Expand Down Expand Up @@ -90,22 +92,35 @@ def start(self) -> None:
pass


def test_process_crash_triggers_stop() -> None:
"""When the native process dies unexpectedly, the watchdog calls stop()."""
@pytest.fixture
def crash_module() -> Generator[StubNativeModule, None, None]:
"""Create a StubNativeModule that dies after 0.2s, ensuring cleanup."""
before = {t.ident for t in threading.enumerate()}
mod = StubNativeModule(die_after=0.2)
mod.pointcloud.transport = LCMTransport("/pc", PointCloud2)
mod.start()
yield mod
# The watchdog calls stop() from its own thread, which sets
# _module_closed=True. A second stop() from here is then a no-op,
# so we explicitly join any threads the test created.
for t in threading.enumerate():
if t.ident not in before and t is not threading.current_thread():
t.join(timeout=5)


def test_process_crash_triggers_stop(crash_module: StubNativeModule) -> None:
"""When the native process dies unexpectedly, the watchdog calls stop()."""
crash_module.pointcloud.transport = LCMTransport("/pc", PointCloud2)
crash_module.start()

assert mod._process is not None
pid = mod._process.pid
assert crash_module._process is not None
pid = crash_module._process.pid

# Wait for the process to die and the watchdog to call stop()
for _ in range(30):
time.sleep(0.1)
if mod._process is None:
if crash_module._process is None:
break

assert mod._process is None, f"Watchdog did not clean up after process {pid} died"
assert crash_module._process is None, f"Watchdog did not clean up after process {pid} died"


@pytest.mark.slow
Expand Down