diff --git a/src/rai_core/rai/communication/ros2/context.py b/src/rai_core/rai/communication/ros2/context.py index 9d12fa5d9..21675bbcc 100644 --- a/src/rai_core/rai/communication/ros2/context.py +++ b/src/rai_core/rai/communication/ros2/context.py @@ -154,7 +154,11 @@ def __init__( period_sec: float = 0.5, setters: Optional[List[Callable]] = None, ) -> None: - self.period_sec = period_sec + if not isinstance(period_sec, (int, float)) or isinstance(period_sec, bool): + raise ValueError("period_sec must be a positive number") + if not (period_sec > 0) or period_sec != period_sec: # NaN check + raise ValueError("period_sec must be positive") + self.period_sec = float(period_sec) self.node = node self.topics_and_types: Dict[str, str] = dict() diff --git a/tests/communication_offline/test_node_discovery_period.py b/tests/communication_offline/test_node_discovery_period.py new file mode 100644 index 000000000..03f661d05 --- /dev/null +++ b/tests/communication_offline/test_node_discovery_period.py @@ -0,0 +1,23 @@ +# Copyright (C) 2026 Robotec.AI +from unittest.mock import MagicMock + +import pytest + +from rai.communication.ros2.context import NodeDiscovery + + +def test_node_discovery_rejects_non_positive_period_sec(): + node = MagicMock() + with pytest.raises(ValueError, match="period_sec"): + NodeDiscovery(node, period_sec=0) + with pytest.raises(ValueError, match="period_sec"): + NodeDiscovery(node, period_sec=-1.0) + with pytest.raises(ValueError, match="period_sec"): + NodeDiscovery(node, period_sec=float("nan")) + + +def test_node_discovery_accepts_positive_period_sec(): + node = MagicMock() + d = NodeDiscovery(node, period_sec=0.25) + assert d.period_sec == 0.25 + node.create_timer.assert_called()